Commit Graph

634 Commits (de93ccb0dac0fe27909fcd4c216757894e9867b1)

Author SHA1 Message Date
Dustin e0624a62cf roles/nextcloud: Update to 18.0.2 2020-03-22 11:26:20 -05:00
Dustin 1d0786f46b hosts: Add build2-armv7hl.p.b
*build2-armv7hl.pyrocufflink.blue* is a Raspberry Pi 3 running Fedora
ARM.  It will be used to build software and OS images for other ARM
machines.
2020-03-21 12:42:27 -05:00
Dustin d1a8c1db84 hosts: Add build1-aarch64.p.b
*build1-aarch64* is a Raspberry Pi 3 B+ running Fedora aarch64.  It is
intended to be used to build software and operating system images for
other aarch64 machines.
2020-03-21 12:42:27 -05:00
Dustin aef175b72b ci: Add pipeline for Nextcloud 2020-03-20 11:03:04 -05:00
Dustin 825e6164d9 ci: Add pipeline for Bitwarden 2020-03-19 07:42:25 -05:00
Dustin 744206fd03 ci: Add pipeline for public websites 2020-03-18 11:40:33 -05:00
Dustin eb4139e0be ci lib: Add applyConfigPolicy pipeline function
The Jenkins pipeline definition files are highly redundant.  Each one
implements almost the same stages, with only a few variations.  Whenever
a new pipeline is added, it's copied from the most recent file and
modified.  If any improvements are made to it, they do not usually get
implemented in any of the existing pipelines.

To address this, the `applyConfigPolicy` pipeline library function is
now available.  This function generates the full pipeline for a
particular application, including stages for setup, each individual
playbook, and cleanup.  Using this function, pipeline files can be as
simple as:

    @Library('cfgpol')_

    applyConfigPolicy(
        'gitea',
        [
            'Gitea': [
                'gitea.yml',
            ],
        ]
    )

This will create a pipeline that mounts the root filesystem read-write
on all hosts in the "gitea" group (any Ansible host pattern is allowed),
applies the `gitea.yml` playbook (in a stage named "Gitea"), and then
remounts the filesystems read-only.

Since this "library" is so simple, containing only a single function in
a single file, and since it will not be used by any pipelines outside
this repository, it makes sense to keep it in this repository, instead
of a separate repository as is customary for Jenkins pipeline shared
libraries.
2020-03-18 11:29:35 -05:00
Dustin 583de8d6ea pyrocufflink-dhcp: Reassign 172.30.0.6 to web0.p.b
The TCP ports 80 and 443 are NAT-forwarded by the gateway to 172.30.0.6.
This address was originally occupied by *rprx0.pyrocufflink.blue*, which
operated a reverse proxy for Bitwarden, Gitea, Jenkins, Nextcloud,
OpenVPN, and the public web sites.  Now, *web0.pyrocufflink.blue* is
configured to proxy for those services that it does not directly host
itself, effectively making it a web server, a reverse proxy, and a
forward proxy (for OpenVPN only).  Thus, it must take over this address
in order to receive forwarded traffic from the Internet.
2020-03-17 08:45:34 -05:00
Dustin 66c9581d7b hosts: Decommission rprx0.p.b
*rprx0.pyrocufflink.blue* is no longer in operation.
*web0.pyrocufflink.blue* handles incoming HTTP/HTTPS requests directly,
proxying to Bitwarden, OpenVPN, etc. as needed.
2020-03-17 08:45:34 -05:00
Dustin 4c661478b2 hosts: bw0: Use Lego cert 2020-03-17 08:45:34 -05:00
Dustin bb73d28c05 websites/darkchestofwonders.us: Use Lego cert 2020-03-17 08:45:34 -05:00
Dustin e4ecd5d58a websites/proxy: Add reverse proxy configuration
For some time, I have been trying to design a new configuration for the
reverse proxy on port 443 to correctly handle all the types of traffic
on that port.  In the original implementation, all traffic on port 443
was forwarded by the gateway to HAProxy.  HAproxy then used TLS SNI to
route connections to the correct backend server based the requested host
name.  This allowed both HTTPS and OpenVPN-over-TLS to use the same
port, however it was not without issues.  A layer 4 (TCP) proxy like
this "hides" the real source address of clients connecting to the
backend, which makes IP-based security (e.g. rate limiting, blacklists,
etc.) impossible at the application level.  In particular, Nextcloud,
which implements rate limiting was constantly imposing login delays on
all users, because legitimate traffic was indistinguishable from
Internet background noise.

To alleviate these issues, I needed to change the proxy to operate in
layer 7 (HTTP) mode, so that headers like *X-Forwarded-For* and
*X-Forwarded-Host* could be added.  Unfortunately, this was not easy,
because of the simultaneous requirement to forward OpenVPN traffic.
HAProxy can only do SNI inspection in TCP mode.  So, I began looking for
an alternate way to proxy both HTTP and non-HTTP traffic on the same
port.

The HTTP protocol defines the `CONNECT` method, which is used by forward
proxies to tunnel HTTPS over plain HTTP.  OpenVPN clients support
tunneling OpenVPN over HTTP using this method as well.  HAProxy has
limited support for the CONNECT method (i.e. it doesn't do DNS
resolution, and I could find no way of restricting the destination) with
the `http_proxy` option, so I looked for alternate proxy servers that
had more complete support.  Unsurprisingly, Apache HTTPD has the most
complete implementation of the `CONNECT` method (Nginx doesn't support
it at all).  Using a name-based virtual host on port 443, Apache will
accept requests for *vpn.pyrocufflink.net* (using TLS SNI) and allow the
clients to use the `CONNECT` method to create a tunnel to the OpenVPN
server.  This requires OpenVPN clients to a) use *stunnel* to wrap plain
HTTP proxy connections in TLS and b) configure OpenVPN to use the
TLS-wrapped HTTP proxy.

With Apache accepting all incoming connections, it was trivial to also
configure it as a layer 7 forward proxy for Bitwarden, Gitea, Jenkins,
and Nextcloud.  Unfortunately, proxying for the other websites
(darkchestofwonders.us, chmod777.sh, dustin.hatch.name) was not quite as
straightforward.  These websites would need to have an internal name
that differed from their external name, and thus a certificate valid for
that name.  Rather than reconfigure all of these sites and set all of
that up, I decided to just move the responsibility for handling direct
connections from outside to the *web0* and eliminate the dedicated
reverse proxy.  This was not possible before, because Apache could not
forward the OpenVPN traffic directly, but now with the forward proxy
configuration, there is no reason to have a separate server for these
connections.

Overall, I am pleased with how this turned out.  It makes the OpenVPN
configuration simpler (*stunnel* no longer needs to run on the OpenVPN
server itself, since Apache is handling TLS termination), eliminates a
network hop for the websites, makes the reverse proxy configuration for
the other web applications much easier to understand, and resolves the
original issue of losing client connection information.
2020-03-16 14:19:08 -05:00
Dustin 1de8e9fa90 websites/pyrocufflink.net: Add HTTP virtual host
A name-based HTTP (not HTTPS)  virtual host for *pyrocufflink.net* is
necessary to ensure requests are handled properly, now that there is
another HTTP virtual host (chmod777.sh) defined on the same server.
2020-03-16 14:17:51 -05:00
Dustin 0694594445 websites/pyrocufflink.net: Use lego certificate
This commit updates the configuration for *pyrocufflink.net* to use the
wildcard certificate managed by *lego* instead of an unique certificate
managed by *certbot*.
2020-03-16 14:16:34 -05:00
Dustin f4510972f4 websites: add tags to each included role
Specifying a unique tag for each website role included in the
`websites.yml` playbook will allow convenient partial runs of the
playbook to deploy a subset of the websites it manages.
2020-03-16 14:15:44 -05:00
Dustin db6d13013a websites: Add chmod777.sh
*chmod777.sh* is a simple static website, generated by Hugo.  It is
built and published from a Jenkins pipeline, which runs automatically
when new commits are pushed to Gitea.

The HTTPS certificate for this site is signed by Let's Encrypt and
managed by `lego` in the `certs` submodule.
2020-03-09 20:29:52 -05:00
Dustin 2b49c5a02e roles/dch-proxy: Configure proxy for Nextcloud
This commit adds front-end and back-end configuration for HAProxy to
proxy HTTP/HTTPS for
*nextcloud.pyrocufflink.net*/*nextcloud.pyrocufflink.blue* to
*cloud0.pyrocufflink.blue*.
2020-03-09 20:24:28 -05:00
Dustin b09bf84a3b nextcloud: Deploy Nextcloud w/ Apache+PHP-FPM
The *nextcloud* role installs Nextcloud from the specified release
archive, downloading it to the control machine first if necessary, and
configures Apache and PHP-FPM to serve it.

The `nextcloud.yml` playbook uses the *cert* role to install the X.509
certificate for the Nextcloud server, sets up Apache HTTPD with the
*apache* role, and installs Nextcloud using the *nextcloud* role.

The host *cloud0.pyrocufflink.blue* is the Nextcloud server for
Pyrocufflink.
2020-03-09 20:18:07 -05:00
Dustin 2aaf8c5239 roles/cert: Common role for installing certs
The *cert* role is intended to be a generic, reusable role to copy an
X.509 certificate and/or private key file to managed nodes.  It is
intended to be included in a playbook with at least the `cert_src` and
`cert_dest` variables defined, e.g.:

```
- hosts: whatever
  roles:
  - role: cert
    cert_src: whatever.cer
    cert_dest: /path/to/whatever.cer
```
2020-03-09 20:17:47 -05:00
Dustin 2d6ed6639e certs/samba: Add CAs to Samba certificate chain
For reasons that totally elude me, Gitea LDAP authentication suddenly
stopped working, citing an error about not trusting the server's
certificate.  I thought this was probably some change in a recent
version of Gitea or Go that changed how the system trust store was used,
but it turned out the problem was actually that Samba was not sending
the intermediate CA certificate.  I am not sure if this was always the
case, and the fact that it worked before was a coincidence, or if
something changed in Samba.  In any case, the fix was (apparently) to
include the intermediate and root CA certificates in the server
certificate file.
2020-03-09 18:11:16 -05:00
Dustin dd0892e208 roles/haproxy: Fix undefined var on Fedora hosts
the `haproxy_ssl_default_bind_options` variable is not defined for
machines running Fedora, because this parameter is not used in the
default configuration file there.
2020-03-03 19:27:19 -06:00
Dustin 1b32a28dd8 certs: Add logo symlink
The `logo` symbolic link under `certs` serves as a more convenient path
for the certificates in the `.certs` submodule.  Roles can refer to
certificates using this path instead of the submodule directly.
2020-03-03 19:02:24 -06:00
Dustin 29e713f862 ci: Add pipeline for Gitea 2020-02-22 16:43:46 -06:00
Dustin cd1cf38774 hosts: git0: Switch to Lego wildcard cert 2020-02-22 16:43:46 -06:00
Dustin f8b7f28469 roles/gitea: Install from upstream binary
I seem to have forgotten how I got the RPM for Gitea.  I think I built
it, but I cannot find the spec file, nor the RPM package.  Since this is
clearly not reproducible, I decided to switch to using the binary
provided by upstream for now, until either I or Fedora get around to
making a better RPM.

Installing Gitea from the upstream binary is simple: just download it
and copy it to `/usr/local/bin`.  Of course, the OS user and systemd
unit have to be managed by configuration policy when it's installed this
way.
2020-02-22 16:43:46 -06:00
Dustin 2bc2ea65ac certs: Add certificates submodule
The *certs* repository contains certificates issued by Let's Encrypt
automatically using Lego.  A Jenkins job runs daily to renew these
certificates as needed, and commit updated certificate files to the
repository.

To deploy these certificates to the applications that use them,
jobs will need to be scheduled to apply configuration policy for those
applications regularly.  Using symlinks to the files in this submodule,
Ansible can deploy those files whenever they change.
2020-02-22 16:28:06 -06:00
Dustin 7543815e9b hosts: Add burp1.p.b
*burp1.pyrocufflink.blue* will replace *burp0.pyrocufflink.blue* as the
BURP server for Pyrocufflink.  It is a physical machine (Fitlet), making
it simpler to manage the USB drives.  The old virtual machine will be
decommissioned soon.
2020-01-25 13:57:04 -06:00
Dustin d290eca833 roles/burp-server: switch to version_compare test
Ansible replaced the `version_compare` filter with a `version_compare`
test that does the same thing.  The former is completely gone now,
causing the template to fail to render, so its usage of that filter
needs to be updated.
2020-01-25 13:54:42 -06:00
Dustin 87843e5926 burp-client: Use burp.p.b name
Using the generic *burp.pyrocufflink.blue* name will allow easier
transition to a new BURP server.  However, since this is not the actual
name, it cannot be used for task delegation, so a separate variable is
required to store the real name of the BURP server.  This is only used
during client deployment, and not by BURP itself.
2020-01-18 12:10:53 -06:00
Dustin e25b9a2e8e hosts: Add logs0.p.b
*logs0.pyrocufflink.blue* hosts Graylog
2019-10-28 18:47:09 -05:00
Dustin b137cd42fa graylog: Add PB to deploy Graylog server
The `graylog.yml` playbook installs Elasticsearch, MongoDB, and Graylog
on a single machine.
2019-10-28 18:47:09 -05:00
Dustin 3aad9c1dda roles/graylog: Add Graylog server deployment
The *graylog* role installs Graylog from the *graylog2.org* Yum
repository and manages basic server configuration.  It augments the
default systemd unit to provide the `CAP_NET_BIND_SERVICE` capability to
the Graylog server process via ambient capabilities, thereby allowing
the server to bind to the privileged Syslog UDP port.
2019-10-28 18:47:09 -05:00
Dustin 07eb3633e3 roles/mongodb: Add MongoDB deployment
The *mongodb* role installs MongoDB from the *mongodb.org* Yum
repository and manages basic server configuration.
2019-10-28 18:34:45 -05:00
Dustin dd4ccb3a32 roles/elasticsearch: Add Elasticsearch deployment
The *elasticsearch* role installs Elasticsearch from the Elastic.co Yum
repository and manages basic node configuration.
2019-10-28 18:33:37 -05:00
Dustin cf8180a195 bitwarden_rs: Fix path to BURP backup script 2019-09-27 14:07:29 -05:00
Dustin 0dc6a80ea2 taiga: Add playbook for Taiga
The `taiga.yml` playbook deploys all the necessary components to run
*taiga-back*, *taiga-front*, and *taiga-events*.
2019-09-19 19:51:45 -05:00
Dustin fab662bd53 hosts: hass0: Add untracked host_vars file 2019-09-19 19:50:35 -05:00
Dustin 02653f7e7c ansible.cfg: Disable stupid group name warning
For some reason, Ansible developers felt like it was important that
users name their host groups according to Python identifier naming
conventions.  This prevents, among other things, hyphens from being used
in group names.  Luckily, this ridiculous behavior is configurable.
2019-09-19 19:50:35 -05:00
Dustin c57de29054 roles/hass-dhcp: Enable DNS query logging 2019-09-19 19:50:35 -05:00
Dustin a1c90272b5 roles/freeradius: Set dhparam permissions
The `dhparam` file used by FreeRadius needs to be readable by the
*radiusd* group.
2019-09-19 19:50:35 -05:00
Dustin 2914bdb73c roles/certbot: Ensure certbot is configured first
The `Alias` configuration for Certbot needs to be configured before any
other locations, to ensure the `/.well-known` path is always served from
the local filesystem.  If another drop-in configuration file (e.g.
`bitwarden.conf`) is ordered before it, it may override this
configuration and prevent Let's Encrypt from working.
2019-09-19 19:50:35 -05:00
Dustin fb352cc920 jenkins-slave: Allow Jenkins to connect to Docker
In order to allow Jenkins to connect to the Docker daemon socket, the
socket must be owned by the *docker* group, and the *jenkins* user must
be a member of it.
2019-09-19 19:50:35 -05:00
Dustin b2cc467581 hosts: Add build0-amd64
*build0-amd64.securepassage.com* is a Jenkins agent that runs Docker,
allowing pipeline jobs to run inside containers.
2019-09-19 19:50:35 -05:00
Dustin 43deb1f89e hosts: Remove references to zabbix-server
Having an empty (therefore undefined) group as the child of another
group causes Ansible to emit a "warning" (really an error) indicating
that it cannot parse the inventory file:

    [WARNING]:  * Failed to parse
    /var/lib/jenkins/workspace/CfgMgmt/pyrocufflink/hosts with ini plugin:
    /var/lib/jenkins/workspace/CfgMgmt/pyrocufflink/hosts:60: Section
    [smtp- relay:children] includes undefined group: zabbix-server
2019-09-19 19:50:35 -05:00
Dustin e3e30eea1c hosts: dns0: Update DHCP server address
Now that the DHCP server has moved from *dns1* to *dns0*, the DNS server
needs to be updated to allow DDNS updates from the latter.
2019-09-19 19:27:30 -05:00
Dustin 1bb9c28ef4 pyrocufflink-dhcp: Add lease for serial0.p.b
*serial0.pyrocufflink.blue* has a manually-configured IP address now, to
ensure it always has an addresss, even if the DHCP server is
unavailable.  Recording it here to ensure the address does not
accidentally get reused.
2019-09-19 19:27:30 -05:00
Dustin c676aa2a0b roles/dch-proxy: Add haproxy config for Bitwarden
This commit adds an HAProxy backend for Bitwarden, and adds ACL rules to
the frontend to proxy traffic to *bitwarden.pyrocufflink.blue* or
*bitwarden.pyrocufflink.net* to it.
2019-09-19 19:27:30 -05:00
Dustin c68f9bb6af hosts: dc0.p.b: Renew Samba TLS certificate
Since the same certificate is used for LDAPS and RADIUS (EAP-TLS), it
makes more sense to store it only once, with the later file as a symlink
to the former.
2019-09-19 19:27:30 -05:00
Dustin 6e57abfe2e bitwarden_rs: Configure BURP client
This commit configures *bw0.pyrocufflink.blue* as a BURP client, so that
the Bitwarden data can be backed up.  A pre-backup script is used to
take a consistent snapshot of the SQLite database before copying it to
the BURP server.
2019-09-19 19:27:30 -05:00
Dustin e095f64126 burp-client: Apply the cronie role
Since the `burp` client command is scheduled to run using Cron, Cronie
needs to be installed and set up in order for the *burp-client* role to
install its cron table file.
2019-09-19 19:27:30 -05:00