Home Network Server Notes

HACKS

$ sudo nmcli connection modify Fios-F5SCq ipv4.routes "192.168.8.0/24 192.168.1.200"
$ sudo nmcli connection modify Fios-F5SCq ipv4.dns "192.168.8.21,192.168.8.22,1.1.1.1,8.8.8.8"
$ sudo nmcli connection modify Fios-F5SCq ipv4.dns-search orionarts.io
$ sudo nmcli connection down Fios-F5SCq
$ sudo nmcli connection up Fios-F5SCq

Proxmox

Install Proxmox

Remove Subscription Nag Screen

$ wget https://raw.githubusercontent.com/foundObjects/pve-nag-buster/master/install.sh
$ bash install.sh
$ rm install.sh

Change Web GUI Port

$ nft add table ip nat
$ nft -- add chain ip nat prerouting { type nat hook prerouting priority -100 \; }
$ nft add rule ip nat prerouting tcp dport 443 redirect to :8006
$ systemctl enable --now nftables

Install Necessary Packages

$ apt update
$ apt upgrade
$ apt install sudo

Configure sshd

$ sed -i -e 's/.*PermitRootLogin.*/PermitRootLogin no/' \
         -e 's/.*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
$ systemctl restart sshd

Download Container Images

Certificate Authority

Create Root CA

Create LXC Container

Hostname: root-ca Unprivileged container Template: Alpine Linux Disk size: 0.1

Initial Configuration

# Install packages
$ apk update
$ apk add openssl

# Create non-root user
$ adduser -h /home/caadmin caadmin
$ su - caadmin

# Prepare PKI
$ mkdir easyrsa
$ wget -qO- https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.1/EasyRSA-3.1.1.tgz | tar zxvf - --strip-components=1 -C easyrsa

# At this point, remove network access permanently

$ cd easyrsa
$ ./easyrsa init-pki
# Generate encrypted passphrase file
$ (umask 077; head -c30 </dev/urandom | base64 > passphrase)

# Edit vars file
$ sed -e 's/^#.*set_var EASYRSA_REQ_COUNTRY.*/set_var EASYRSA_REQ_COUNTRY\t"US"/' \
      -e 's/^#.*set_var EASYRSA_REQ_PROVINCE.*/set_var EASYRSA_PROVINCE\t"Maryland"/' \
      -e 's/^#.*set_var EASYRSA_REQ_CITY.*/set_var EASYRSA_CITY\t\t"Baltimore"/' \
      -e 's/^#.*set_var EASYRSA_REQ_ORG.*/set_var EASYRSA_REQ_ORG\t\t"Orion Arts"/' \
      -e 's/^#.*set_var EASYRSA_REQ_EMAIL.*/set_var EASYRSA_REQ_EMAIL\t"ca-admin@orionarts.io"/' \
      vars.example > pki/vars

# Build Root CA
$ ./easyrsa --passin=file:passphrase --passout=file:passphrase --req-cn="Orion Arts Root CA" --batch build-ca

Create Intermediate CA

Create LXC Container

Hostname: root-ca Unprivileged container Template: Alpine Linux Disk size: 0.1

Initial Configuration

# Install packages
$ apk update
$ apk add openssl

# Create non-root user
$ adduser -h /home/caadmin caadmin
$ su - caadmin

# Prepare PKI
$ mkdir easyrsa
$ wget -qO- https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.1/EasyRSA-3.1.1.tgz | tar zxvf - --strip-components=1 -C easyrsa

# At this point, remove network access permanently

$ cd easyrsa
$ ./easyrsa init-pki
# Generate encrypted passphrase file
$ (umask 077; head -c30 </dev/urandom | base64 > passphrase)

# Edit vars file
$ sed -e 's/^#.*set_var EASYRSA_REQ_COUNTRY.*/set_var EASYRSA_REQ_COUNTRY\t"US"/' \
      -e 's/^#.*set_var EASYRSA_REQ_PROVINCE.*/set_var EASYRSA_PROVINCE\t"Maryland"/' \
      -e 's/^#.*set_var EASYRSA_REQ_CITY.*/set_var EASYRSA_CITY\t\t"Baltimore"/' \
      -e 's/^#.*set_var EASYRSA_REQ_ORG.*/set_var EASYRSA_REQ_ORG\t\t"Orion Arts"/' \
      -e 's/^#.*set_var EASYRSA_REQ_EMAIL.*/set_var EASYRSA_REQ_EMAIL\t"ca-admin@orionarts.io"/' \
      vars.example > pki/vars

# Generate Sub-CA CSR
$ ./easyrsa --passin=file:passphrase --passout=file:passphrase --req-cn="Orion Arts Sub-CA" --batch build-ca subca

# Generate intermediate CA certificate
# Copy pki/reqs/ca.req to root-ca at easyrsa/pki/reqs/subca.req
$ ./easyrsa --passin=file:passphrase sign-req ca subca

# Create certificate bundle and copy to Intermeidate CA
$ cat pki/issued/subca.crt pki/ca.crt ~/orionarts-bundle.crt

# Copy pki/issued/subca.crt to pki/ca.crt on the Intermediate CA
# Copy ~/orionarts-bundle.crt to the Intermediate CA

FreeIPA

Create LXC Container

Unprivileged container Template: Rocky Linux RAM: 2048 MB Network: static IP address DNS: set to a public DNS server

Install FreeIPA

$ dnf update
$ dnf -y install freeipa-server freeipa-server-dns openssh-server
$ systemctl enable --now sshd
$ ipa-server-install --no-ntp \ # Host system takes care of time sync
                     --domain orionarts.io \
                     --realm ORIONARTS.IO \
                     --hostname fili.orionarts.io \
                     --netbios-name ORIONARTS \
                     --ds-password <Directory Manager Password> \
                     --admin-password <Admin User Password> \
                     --idstart 60001 \ # /etc/login.defs: {UG}ID_MAX is 60000
                     --idmax 65536 \ # maximum mapped {ug}id in host's /etc/sub{ug}id
                     --mkhomedir \
                     --external-ca \
                     --ca-subject "CN=Orion Arts IPA CA, O=ORIONARTS.IO" \
                     --setup-dns \
                     --allow-zone-overlap \ # Google serves the publically accessible members or orionarts.io
                     --forwarder 1.1.1.1 \ # This will change once a local DNS server is set up
                     --forward-policy only \
                     --unattended

# Copy /root/ipa.csr to Intermediate CA at ~caadmin/pki/reqs/ipa.req
sub-ca$ ./easyrsa --passin=file:passphrase sign-req ca ipa

# Copy pki/issued/ipa.crt and orionarts-bundle.crt to FreeIPA server
$ ipa-server-install --external-cert-file=/path/to/signed_certificate --external-cert-file=/path/to/ca/bundle --unattended

# Open ports:
# 80, 443
# 389, 636
# 88, 464
# 88, 464 udp

Configure DNS

$ cat >> /etc/named/ipa-ext.conf <<END
acl "trusted_network" {
    localnets;
    localhost;
    192.168.1.0/24;
    10.36.2.0/24;
};
END
$ echo "allow-recursion { trusted_network; };" >> /etc/named/ipa-options-ext.conf
$ ipactl restart

Create Clients

Pi-hole

Create LXC Container

Unprivileged container Template: Rocky Linux Disk size: 4G Network: static IP address

Install Pi-hole

$ dnf update
$ curl -sSL https://install.pi-hole.net > install.sh
$ PIHOLE_SKIP_OS_CHECK=true bash install.sh
$ rm install.sh
$ pihole -a -p # Set Admin Console Password

Change FreeIPA DNS forwarder to Pi-hole

ipa$ ipa dnsconfig-mod --forwarder <pihole IP> --forward-policy only

Enable HTTPS

# Create CNAME record
$ ipa dnsrecord-add orionarts.io ph01 --cname-hostname dain

# Add the host to FreeIPA, using the cname
$ ipa host-add ph01.orionarts.io

# Create a host principal for the service www
$ ipa service-add www/dain.orionarts.io

# Create a principal for the service www with the cname
$ ipa service-add www/ph01.orionarts.io

# Add the cname principal to the host
$ ipa service-add-host www/ph01.orionarts.io --host dain.orionarts.io

# Request a certificate for the host, using the principal and private key and cname
$ ipa-getcert request -r \
    -f /etc/pki/tls/certs/ph01.crt \
    -k /etc/pki/tls/private/server.key \
    -K www/dain.orionarts.io \
    -N dain.orionarts.io \
    -D ph01.orionarts.io

cat /etc/pki/tls/private/server.key /etc/pki/tls/certs/ph01.crt > /etc/pki/tls/certs/combined.pem
chown lighttpd:lighttpd combined.pem
cat > /etc/lighttpd/external.conf <<END
$HTTP["host"] == "ph01.orionarts.io" {
  # Ensure the Pi-hole Block Page knows that this is not a blocked domain
  setenv.add-environment = ("fqdn" => "true")

  # Enable the SSL engine with a LE cert, only for this specific host
  $SERVER["socket"] == ":443" {
    ssl.engine = "enable"
    ssl.pemfile = "/etc/pki/tls/certs/combined.pem"
    ssl.ca-file =  "/etc/ipa/ca.pem"
    ssl.honor-cipher-order = "enable"
    ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
    ssl.use-sslv2 = "disable"
    ssl.use-sslv3 = "disable"
  }

  # Redirect HTTP to HTTPS
  $HTTP["scheme"] == "http" {
    $HTTP["host"] =~ ".*" {
      url.redirect = (".*" => "https://%0$0")
    }
  }
}
$HTTP["host"] == "dain.orionarts.io" {
  # Ensure the Pi-hole Block Page knows that this is not a blocked domain
  setenv.add-environment = ("fqdn" => "true")

  # Enable the SSL engine with a LE cert, only for this specific host
  $SERVER["socket"] == ":443" {
    ssl.engine = "enable"
    ssl.pemfile = "/etc/pki/tls/certs/combined.pem"
    ssl.ca-file =  "/etc/ipa/ca.pem"
    ssl.honor-cipher-order = "enable"
    ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
    ssl.use-sslv2 = "disable"
    ssl.use-sslv3 = "disable"
  }

  # Redirect HTTP to HTTPS
  $HTTP["scheme"] == "http" {
    $HTTP["host"] =~ ".*" {
      url.redirect = (".*" => "https://%0$0")
    }
  }
}
END

Second Pi-hole

$ apt install -y chrony freeipa-client vim-tiny
$ ipa-client-install --mkhomedir --enable-dns-updates
    # Figure out how to make the node server the NTP server

Gitea

# apk add gitea
# apk add mariadb mariadb-client
# mysql_install_db --user=mysql --datadir=/var/lib/mysql
# service mariadb start
# rc-update add mariadb
# mysql_secure_installation
    #
# mysql -u root -p
mysql> CREATE DATABASE gitea DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
mysql> GRANT ALL ON gitea.* TO 'giteauser'@'localhost' IDENTIFIED BY 'giteapassword';
mysql> FLUSH PRIVILEGES;
mysql> EXIT
# vi /etc/gitea/app.ini
    [database]
    DB_TYPE = mysql
    HOST = /var/run/mysqld/mysqld.sock
    NAME = gitea            ; The database name set with 'CREATE DATABASE'
    USER = giteauser        ; The database user
    PASSWD = giteapassword  ; The password for the database user
# rc-update add gitea
# service start gitea

Change HTTPS Certificates to FreeIPA

Request Certificate Without CNAME

# Create a host principal for the service HTTP
ipa service-add www/HOSTNAME.orionarts.io

# Add the host principal to the host
ipa service-add-host HTTP/HOSTNAME.orionarts.io --host HOSTNAME.orionarts.io

# Request a certificate for the host, using the principal and private key
$ ipa-getcert request -r \
    -f /etc/pki/tls/certs/HOSTNAME.crt \
    -k /etc/pki/tls/private/server.key \
    -K www/HOSTNAME.orionarts.io \
?   -N HOSTNAME.orionarts.io \
?   -D CNAME.orionarts.io

Request Certificate With CNAME

# Create CNAME record
$ ipa dnsrecord-add orionarts.io CNAME --cname-hostname HOSTNAME

# Add the host to FreeIPA, using the cname
$ ipa host-add CNAME.orionarts.io

# Create a host principal for the service www
$ ipa service-add www/HOSTNAME.orionarts.io

# Create a principal for the service www with the cname
$ ipa service-add www/CNAME.orionarts.io

# Add the cname principal to the host
$ ipa service-add-host www/CNAME.orionarts.io --host HOSTNAME.orionarts.io

# Request a certificate for the host, using the principal and private key and cname
$ ipa-getcert request -r \
    -f /etc/pki/tls/certs/CNAME.crt \
    -k /etc/pki/tls/private/server.key \
    -K www/HOSTNAME.orionarts.io \
    -N HOSTNAME.orionarts.io \
    -D CNAME.orionarts.io

Server Specific

Proxmox

FreeIPA Replica

Setup Open Media Vault

Install OMV

$ wget -O install.sh https://github.com/OpenMediaVault-Plugin-Developers/installScript/raw/master/install
$ sudo bash install.sh

Configure OMV

After the Pi reboots, login into the OMV web GUI (http://) with username omv and password openmediavault.