add ipv4 support

This commit is contained in:
2024-07-11 12:35:17 -04:00
parent f2f51a923a
commit cecd234160
22 changed files with 374 additions and 101 deletions

View File

@@ -6,6 +6,7 @@ fedora:
hosts:
nextcloud:
kube:
yellow:
ubuntu:
hosts:

View File

@@ -1,6 +1,20 @@
# AWS Credentials
## Aws Certbot Route53 Policies
## Credential Generation
```bash
export AWS_USERNAME=
aws iam create-user --user-name $AWS_USERNAME
aws iam create-access-key --user-name $AWS_USERNAME
# Allow updating reeseapps
aws iam attach-user-policy --user-name $AWS_USERNAME --policy-arn arn:aws:iam::892236928704:policy/update-reeseapps
# Allow updating reeselink
aws iam attach-user-policy --user-name $AWS_USERNAME --policy-arn arn:aws:iam::892236928704:policy/update-reeselink
```
## AWS Certbot Route53 Policies
Example Policy:

View File

@@ -1,5 +1,5 @@
[Unit]
Description=Updates the {{ fqdn }} record with the current public IPV4 address
Description=Updates the IPv4 records with the current public IPV4 address
[Service]
ExecStart=/usr/local/scripts/ddns.sh

View File

@@ -2,11 +2,19 @@
# Get public IP address (there are many ways to do it, I picked this way)
PUBLIC_IP=$(curl -4 ifconfig.me)
# Update *.{{ fqdn }} and {{ fqdn }}
cat /etc/ddns/record_template.json \
| jq '.Changes[0].ResourceRecordSet.ResourceRecords[0].Value = "'$PUBLIC_IP'"' \
> /etc/ddns/record.json
# aws cli to update a record
aws route53 change-resource-record-sets --hosted-zone-id {{ hosted_zone_id }} --change-batch file:///etc/ddns/record.json
PUBLIC_IPV6=$(dig -t aaaa +short myip.opendns.com @resolver1.opendns.com)
# Update reeselink records
cat /etc/ddns/reeselink_record_template.json \
| jq '.Changes[0].ResourceRecordSet.ResourceRecords[0].Value = "'$PUBLIC_IP'"' \
> /etc/ddns/reeselink_record.json
# Update reeseapps records
cat /etc/ddns/reeseapps_record_template.json \
| jq '.Changes[].ResourceRecordSet.ResourceRecords[0].Value = "'$PUBLIC_IP'"' \
> /etc/ddns/reeseapps_record.json
# Update reeselink records
aws route53 change-resource-record-sets --hosted-zone-id Z0092652G7L97DSINN18 --change-batch file:///etc/ddns/reeselink_record.json
# Update reeseapps records
aws route53 change-resource-record-sets --hosted-zone-id Z012820733346FJ0U4FUF --change-batch file:///etc/ddns/reeseapps_record.json

View File

@@ -1,8 +1,5 @@
- name: Update nginx stream configuration
hosts: colors
become: true
become_user: root
become_method: sudo
hosts: yellow
vars_files:
- vars.yaml
tasks:
@@ -29,10 +26,17 @@
path: /etc/ddns
state: directory
mode: '0755'
- name: Copy record_template.json
- name: Copy reeseapps_record_template.json
template:
src: record_template.json
dest: /etc/ddns/record_template.json
src: reeseapps_record_template.json
dest: /etc/ddns/reeseapps_record_template.json
owner: root
group: root
mode: '0644'
- name: Copy reeselink_record_template.json
template:
src: reeselink_record_template.json
dest: /etc/ddns/reeselink_record_template.json
owner: root
group: root
mode: '0644'

View File

@@ -0,0 +1,83 @@
{
"Comment": "Update Public IPV4 Address",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "homeassistant.reeseapps.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": ""
}
]
}
},
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "nextcloud.reeseapps.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": ""
}
]
}
},
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "gitea.reeseapps.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": ""
}
]
}
},
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "git.reeseapps.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": ""
}
]
}
},
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "jellyfin.reeseapps.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": ""
}
]
}
},
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "snapdrop.reeseapps.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": ""
}
]
}
}
]
}

View File

@@ -4,7 +4,7 @@
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "{{ fqdn }}.",
"Name": "ipv4.reeselink.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
@@ -13,6 +13,6 @@
}
]
}
}
}
]
}

View File

@@ -1,2 +0,0 @@
hosted_zone_id: Z0092652G7L97DSINN18
fqdn: ipv4.reeselink.com

View File

@@ -25,4 +25,4 @@ aws route53 change-resource-record-sets --hosted-zone-id Z0092652G7L97DSINN18 --
```bash
aws route53 change-resource-record-sets --hosted-zone-id Z012820733346FJ0U4FUF --change-batch file://dns/reeseapps.json
```
```

View File

@@ -52,6 +52,19 @@
}
]
}
},
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "driveripper.reeselink.com",
"Type": "AAAA",
"TTL": 300,
"ResourceRecords": [
{
"Value": "2600:1700:1e6c:a81f:94bb:b8ff:fe9f:1c63"
}
]
}
}
]
}

View File

@@ -54,6 +54,7 @@ spec:
- --source=service
- --source=ingress
- --domain-filter=reeseapps.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
- --domain-filter=reeselink.com
- --provider=aws
# - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
- --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)

View File

@@ -63,7 +63,7 @@ service:
ipFamilies: ["IPv6"]
annotations:
metallb.universe.tf/address-pool: "external"
external-dns.alpha.kubernetes.io/hostname: git.reeseapps.com
external-dns.alpha.kubernetes.io/hostname: git.reeseapps.com,git.reeselink.com
redis-cluster:

View File

@@ -4,6 +4,7 @@ controller:
annotations:
metallb.universe.tf/address-pool: "external"
metallb.universe.tf/allow-shared-ip: nginx
external-dns.alpha.kubernetes.io/hostname: ingress-nginx.reeselink.com
ipFamilyPolicy: SingleStack
ipFamilies:
- IPv6

24
ipv4-proxy/README.md Normal file
View File

@@ -0,0 +1,24 @@
# IPv4 Proxy
This project aims to serve those without an IPv6 ISP by forwarding IPv4 requests to the
correct destination. This is accomplished by SSL preread and port mapping. This service
is intended only for publicly accessible services.
## DDNS
This project pairs with the ddns service. Set that up first!
## Updating IPv4 Proxy Records
1. In `ddns` create a new record in the `reeseapps_record_template.json`
2. Apply the new record with ansible
3. Update `vars.yaml` in this project
4. Run the following ansible script:
```bash
ansible-playbook -i ansible/inventory.yaml ipv4-proxy/nginx.yaml
```
## Logging
You can tail all the nginx logs with `ssh yellow 'tail -f /var/log/nginx/*.log'`

53
ipv4-proxy/nginx.conf Normal file
View File

@@ -0,0 +1,53 @@
load_module /usr/lib64/nginx/modules/ngx_stream_module.so;
worker_processes auto;
events {
worker_connections 1024;
}
stream {
log_format ssl '| Remote Addr: $remote_addr:$server_port | SSL Preread: $ssl_preread_server_name | Forward: $map_forward_ssl | $time_local | $protocol | $status | $bytes_sent | $bytes_received | $session_time |';
log_format port '| Remote Addr: $remote_addr:$server_port | SSL Preread: $ssl_preread_server_name | Forward: $map_forward_port | $time_local | $protocol | $status | $bytes_sent | $bytes_received | $session_time |';
# Map all SSL parsed server names to hosts
map $ssl_preread_server_name $map_forward_ssl {
{% for item in stream_ssl %}
{{ item.external.domain }} {{ item.internal.domain }}:{{ item.internal.port }};
{% endfor %}
}
server {
access_log /var/log/nginx/nginx_stream_access.log ssl;
error_log /var/log/nginx/nginx_stream_error.log warn;
listen 443;
proxy_pass $map_forward_ssl;
ssl_preread on;
proxy_socket_keepalive on;
resolver 10.1.0.1;
}
map $server_port $map_forward_port {
{% for item in stream_ports %}
{{ item.external }} {{ item.internal }};
{% endfor %}
}
server {
{% for item in stream_ports %}
listen {{ item.external }};
{% endfor %}
access_log /var/log/nginx/nginx_stream_access.log port;
error_log /var/log/nginx/nginx_stream_error.log warn;
listen 443;
proxy_pass $map_forward_port;
proxy_socket_keepalive on;
resolver 10.1.0.1;
}
}

42
ipv4-proxy/nginx.yaml Normal file
View File

@@ -0,0 +1,42 @@
- name: Update nginx stream configuration
hosts: yellow
vars_files:
- vars.yaml
tasks:
- name: Ensure nginx, certbot, and nginx-mod-stream are installed
ansible.builtin.dnf:
name:
- nginx
- nginx-mod-stream
state: present
- name: Remove http.d dir before repopulating
file:
path: /etc/nginx/http.d/
state: absent
- name: Remove stream.d dir before repopulating
file:
path: /etc/nginx/stream.d/
state: absent
- name: Create stream.d dir
ansible.builtin.file:
path: /etc/nginx/stream.d
state: directory
mode: '0755'
- name: Template nginx.conf
template:
src: nginx.conf
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
- name: Test nginx configuration
ansible.builtin.shell: /usr/sbin/nginx -t
- name: Stop nginx service
ansible.builtin.systemd_service:
state: stopped
name: nginx
- name: Reload nginx service
ansible.builtin.systemd_service:
state: started
name: nginx
enabled: true

37
ipv4-proxy/vars.yaml Normal file
View File

@@ -0,0 +1,37 @@
stream_ssl:
- external:
domain: homeassistant.reeseapps.com
internal:
domain: homeassistant.reeselink.com
port: 443
protocol: https
- external:
domain: gitea.reeseapps.com
internal:
domain: ingress-nginx.reeselink.com
port: 443
protocol: https
- external:
domain: nextcloud.reeseapps.com
internal:
domain: nextcloud.reeselink.com
port: 443
protocol: https
- external:
domain: jellyfin.reeseapps.com
internal:
domain: ingress-nginx.reeselink.com
port: 443
protocol: https
- external:
domain: snapdrop.reeseapps.com
internal:
domain: ingress-nginx.reeselink.com
port: 443
protocol: https
stream_ports:
- external: 2222
internal: git.reeselink.com:22
- external: 3478
internal: nextcloud.reeselink.com:3478

View File

@@ -59,92 +59,16 @@ spec:
claimName: {{ .Release.Name }}-cache
- name: movies
nfs:
server: democratic-csi-server.reeselink.com
server: driveripper.reeselink.com
path: /mnt/enc0/media/Movies
readOnly: true
- name: shows
nfs:
server: democratic-csi-server.reeselink.com
server: driveripper.reeselink.com
path: /mnt/enc0/media/Shows
readOnly: true
- name: videos
nfs:
server: democratic-csi-server.reeselink.com
server: driveripper.reeselink.com
path: /mnt/enc0/media/Videos
readOnly: true
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .Release.Name }}-config
annotations:
"helm.sh/resource-policy": keep
spec:
storageClassName: zfs-iscsi-enc0
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .Release.Name }}-cache
annotations:
"helm.sh/resource-policy": keep
spec:
storageClassName: zfs-iscsi-enc1
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 128Gi
---
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: jellyfin
ports:
- name: http
protocol: TCP
port: 80
targetPort: http
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}
annotations:
cert-manager.io/cluster-issuer: letsencrypt
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.org/client-max-body-size: "0"
spec:
rules:
- host: {{ .Values.jellyfin.domain }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jellyfin
port:
name: http
tls:
- hosts:
- {{ .Values.jellyfin.domain }}
secretName: jellyfin-tls-cert

View File

@@ -0,0 +1,25 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}
annotations:
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.org/client-max-body-size: "0"
spec:
ingressClassName: nginx
rules:
- host: {{ .Values.jellyfin.domain }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jellyfin
port:
name: http
tls:
- hosts:
- {{ .Values.jellyfin.domain }}
secretName: jellyfin-tls-cert

View File

@@ -0,0 +1,27 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .Release.Name }}-config
annotations:
"helm.sh/resource-policy": keep
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .Release.Name }}-cache
annotations:
"helm.sh/resource-policy": keep
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 16Gi

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
spec:
ipFamilyPolicy: PreferDualStack
ipFamilies:
- IPv6
- IPv4
type: ClusterIP
selector:
app.kubernetes.io/name: jellyfin
ports:
- name: http
protocol: TCP
port: 80
targetPort: http

View File

@@ -195,6 +195,7 @@ spec:
```bash
aws iam create-user --user-name "externaldns"
aws iam attach-user-policy --user-name "externaldns" --policy-arn arn:aws:iam::892236928704:policy/update-reeseapps
aws iam attach-user-policy --user-name "externaldns" --policy-arn arn:aws:iam::892236928704:policy/update-reeselink
SECRET_ACCESS_KEY=$(aws iam create-access-key --user-name "externaldns")
ACCESS_KEY_ID=$(echo $SECRET_ACCESS_KEY | jq -r '.AccessKey.AccessKeyId')