9 Commits

Author SHA1 Message Date
44c7978812 Working cross-compile 2022-01-11 16:58:10 -05:00
9df741b040 Switch to using allow-update 2022-01-11 16:35:54 -05:00
d3fb621ca9 Fix README 2021-12-18 18:36:07 -05:00
eee688245e Update README 2021-12-18 18:35:17 -05:00
eba140be0b Working ansible recipe 2021-12-18 18:33:45 -05:00
baf329f11c Working devops 2021-12-18 18:13:52 -05:00
a9171c5f21 Working devops 2021-12-18 17:58:48 -05:00
d4d9ab3f9f Add examples to README 2021-12-18 10:36:12 -05:00
95db71be61 deploy_binary.sh 2021-12-06 17:49:04 +01:00
24 changed files with 456 additions and 30 deletions

4
.cargo/config Normal file
View File

@ -0,0 +1,4 @@
[target.x86_64-unknown-linux-musl]
linker = "x86_64-unknown-linux-musl-gcc"
objcopy = { path ="x86_64-unknown-linux-musl-objcopy" }
strip = { path ="x86_64-unknown-linux-musl-strip" }

2
.gitignore vendored
View File

@ -4,3 +4,5 @@ ns_tests/*.key
ns_tests/* ns_tests/*
.DS_Store .DS_Store
bash bash
devops/hosts
.idea

2
Cargo.lock generated
View File

@ -1051,7 +1051,7 @@ dependencies = [
[[package]] [[package]]
name = "peach-dyndns-server" name = "peach-dyndns-server"
version = "0.1.0" version = "0.1.2"
dependencies = [ dependencies = [
"clap-log-flag", "clap-log-flag",
"clap-verbosity-flag", "clap-verbosity-flag",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "peach-dyndns-server" name = "peach-dyndns-server"
version = "0.1.0" version = "0.1.2"
authors = ["Michael Williams <michael.williams@enspiral.com>", "Max Fowler <notplants@mfowler.info>"] authors = ["Michael Williams <michael.williams@enspiral.com>", "Max Fowler <notplants@mfowler.info>"]
edition = "2018" edition = "2018"
@ -31,5 +31,5 @@ assets = [
["target/release/peach-dyndns-server", "usr/bin/", "755"], ["target/release/peach-dyndns-server", "usr/bin/", "755"],
["debian/reloadbind", "usr/bin/", "755"], ["debian/reloadbind", "usr/bin/", "755"],
["debian/bindctl", "/etc/sudoers.d/bindctl", "655"], ["debian/bindctl", "/etc/sudoers.d/bindctl", "655"],
["templates/*", "/srv/peachcloud/peach-dyndns-server/prod-peach-dyndns/templates/", "644"], ["templates/*", "/srv/peach-dyndns-server/templates/", "644"],
] ]

View File

@ -1,18 +1,13 @@
# peach-dyndns-host # peach-dyndns-server
a dynamic DNS server to host the names of guests with changing IP addresses a dynamic DNS server to host the names of guests with changing IP addresses
by providing an http API for updating bind9 configurations. by providing an http API for updating bind9 configurations.
## Setup ## Deployment
The code in this repo assumes the existence of an installed and running bind9 server on the same The bind9 server and peach-dyndns-server can be deployed with ansible vis setup_server.sh
server as is running peach-dyndns-server. Documentation for setting up bind9 can be found [here](docs/setup-bind-for-peach-dyndns.md).
The peach-dyndns-server code can be compiled with
```
cargo deb; sudo dpkg -i target/debian/peach-dyndns-server_0.1.0_amd64.deb
```
## Development ## Development
@ -20,22 +15,64 @@ cargo deb; sudo dpkg -i target/debian/peach-dyndns-server_0.1.0_amd64.deb
sudo su peach-dyndns; ./target/release/main -vv sudo su peach-dyndns; ./target/release/main -vv
``` ```
## Prod Deployment
prod is deployed to /srv/peachcloud/peach-dyndns-server/prod-peach-dyndns
## Staging Deployment
staging is deployed to /srv/peachcloud/peach-dyndns-server/dev-peach-dyndns
## Test ## Test
test peach-dyndns server is running, ### ping
``` ```
curl http://localhost:8000 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "ping", "id":1 }' 127.0.0.1:3002
``` ```
test peach-bind9 is running, ### register_domain
``` ```
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "register_domain", "params" : {"domain": "mirage.dyn.peachcloud.org" }, "id":1 }' 127.0.0.1:3002
```
### is_domain_available
```
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "is_domain_available", "params" : {"domain": "mirage.dyn.peachcloud.org" }, "id":1 }' 127.0.0.1:3002
```
# register_domain
```
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "register_domain", "params" : {"domain": "mirage.dyn.peachcloud.org" }, "id":1 }' 127.0.0.1:3002
```
# is_domain_available
```
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "is_domain_available", "params" : {"domain": "mirage.dyn.peachcloud.org" }, "id":1 }' 127.0.0.1:3002
```
# test peach-bind9 is running,
```
# this returns version of bind running
dig -t txt -c chaos VERSION.BIND @IP_ADDRESS_OF_SERVER
# this returns records for blue.dyn.peachcloud.org
nslookup blue.dyn.peachcloud.org YOUR_SERVER_IP_ADDRESS
# this returns records for blue.dyn.peachcloud.org
nslookup blue.dyn.peachcloud.org ns.peachcloud.org nslookup blue.dyn.peachcloud.org ns.peachcloud.org
``` ```
# test nsupdate is working
```
/usr/bin/nsupdate -k /var/lib/peachcloud/peach-dyndns/tsig.key -v <<EOF
server ns.peachcloud.org
zone bluemirage889.dyn.peachcloud.org
update delete bluemirage889.dyn.peachcloud.org
update add bluemirage889.dyn.peachcloud.org 30 A 174.76.52.101
send
EOF
```
```
cat <<EOF | /usr/bin/nsupdate -k /var/lib/peachcloud/peach-dyndns/tsig.key -v
server ns.peachcloud.org
zone bluemirage889.dyn.peachcloud.org
update delete bluemirage889.dyn.peachcloud.org
update add bluemirage889.dyn.peachcloud.org 30 A 174.76.52.101
send
EOF
```

View File

@ -1,3 +1,3 @@
[default] [default]
template_dir = "templates/" template_dir = "devops/templates/tera"
port = 3001 port = 3001

3
cross_compile.sh Executable file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
cargo build --release --target=x86_64-unknown-linux-musl
cp target/x86_64-unknown-linux-musl/release/peach-dyndns-server devops/files/peach-dyndns-server

5
deploy_binary.sh Executable file
View File

@ -0,0 +1,5 @@
VERSION=0.1.2
scp -i ~/.ssh/do_rsa2 target/x86_64-unknown-linux-musl/release/peach-dyndns-server root@147.182.177.135:/srv/files.commoninternet.net/peach-dyndns-server_${VERSION}_Linux_x86_64

64
devops/deploy.yml Normal file
View File

@ -0,0 +1,64 @@
---
- hosts: webservers
user: ubuntu
sudo: True
tasks:
- include_vars: vars.yaml
- name: ensure log directory
action: file dest={{log_dir}} state=directory
- name: deploy code from repository
git: repo={{repo_url}} dest={{src_dir}} remote={{repo_remote}} version={{repo_branch}} accept_hostkey=yes
notify:
- restart nginx
- restart webapp
- name: install python requirements
action: pip requirements={{src_dir}}/requirements.txt state=present
- name: copy hellow_webapp.ini
action: template src=templates/hello_webapp.ini dest={{src_dir}}/hello_webapp.ini
- name: create nginx site config
action: template src=templates/nginx_site.conf dest=/etc/nginx/sites-available/{{app_name}}.conf
notify:
- restart nginx
- name: link nginx config
action: file src=/etc/nginx/sites-available/{{app_name}}.conf dest=/etc/nginx/sites-enabled/{{app_name}}.conf state=link
- name: create upstart script for webapp
action: template src=templates/hello_webapp.conf dest=/etc/init/hello_webapp.conf
- name: ensure secrets directory
action: file dest={{src_dir}}/devops/secret_files state=directory
- name: Copy secret.json file
copy: src=secret_files/secret.json dest={{src_dir}}/devops/secret_files/secret.json
- name: make src_dir writeable by webgroup
action: file path={{src_dir}} mode=u=rwX,g=rwX,o=X recurse=yes group=webgroup
- name: make log_dir writeable by webgroup
action: file path={{log_dir}} mode=u=rwX,g=rwX,o=X recurse=yes group=webgroup
# - name: crontab to check alerts
# cron: name="check alerts" minute="*" job="curl {{prod_url}}/get_all_tix/"
- name: restart server and webapp
command: /bin/true
notify:
- restart nginx
- restart webapp
handlers:
- name: restart nginx
action: service name=nginx state=restarted
- name: restart webapp
action: service name={{app_name}} state=restarted

BIN
devops/files/peach-dyndns-server Executable file

Binary file not shown.

144
devops/setup_server.yml Normal file
View File

@ -0,0 +1,144 @@
---
- hosts: dyndnsservers
user: root
tasks:
- include_vars: vars.yaml
- name: Run the equivalent of "apt-get update"
apt:
update_cache: yes
- name: Install the version '1.14.2' of package "nginx" and allow potential downgrades
apt:
name: nginx=1.18.0-6.1
state: present
allow_downgrade: yes
- name: write nginx.conf
action: template src=templates/nginx.conf dest=/etc/nginx/nginx.conf
- name: Install bind9 packages
apt:
pkg:
- bind9
- python3-dnspython
- dnsutils
- name: Ensure group bind exists
ansible.builtin.group:
name: bind
state: present
- name: Create peach-dyndns user and add to bind group
ansible.builtin.user:
name: peach-dyndns
shell: /bin/bash
system: true
groups: bind
append: yes
- name: Create peach-dyndns-server service
template:
src: templates/peach-dyndns-server.service
dest: /lib/systemd/system/peach-dyndns-server.service
- name: Copy /etc/bind/named.conf
template:
src: "templates/named.conf"
dest: /etc/bind/named.conf
owner: root
group: root
mode: 0644
notify:
- reload bind9
- name: Copy /etc/sudoers.d/bindctl
template:
src: "templates/bindctl"
dest: /etc/sudoers.d/bindctl
owner: root
group: root
mode: 0655
notify:
- reload bind9
- name: Copy /usr/bin/reloadbind
ansible.builtin.copy:
src: templates/reloadbind
dest: /usr/bin/reloadbind
owner: root
group: root
mode: '0755'
- name: Copy /usr/bin/peach-dyndns-server
ansible.builtin.copy:
src: files/peach-dyndns-server
dest: /usr/bin/peach-dyndns-server
owner: peach-dyndns
group: root
mode: '0755'
- name: create dyndns working directory
file:
path: /srv/peach-dynddns-server
state: directory
- name: create templates directory
file:
path: /srv/peach-dyndns-server/templates/
state: directory
- name: Copy zonefile.tera
ansible.builtin.copy:
src: "templates/tera/zonefile.tera"
dest: /srv/peach-dynddns-server/templates/zonefile.tera
owner: root
group: bind
mode: 0644
- name: Create dynserver nginx site conf
template:
src: "templates/dynserver_nginx.conf"
dest: /etc/nginx/sites-enabled/dynserver.conf
notify:
- reload nginx
- name: Touch keys file
ansible.builtin.file:
path: /etc/bind/dyn.peachcloud.org.keys
state: touch
mode: "u=rw,g=rw"
- name: Recursively set permissions for /etc/bind
ansible.builtin.file:
path: /etc/bind
state: directory
recurse: yes
owner: root
group: bind
mode: 'u+rwX,g+rwX'
- name: start peach-dyndns-server
systemd: state=started name=peach-dyndns-server daemon_reload=yes
- name: start bind9
systemd: state=started name=bind9 daemon_reload=yes
- name: start nginx
systemd: state=started name=nginx daemon_reload=yes
handlers:
- name: reload bind9
service: name=bind9 state=reloaded
- name: reload peach-dyndns-server
service: name=peach-dyndns-server state=reloaded
- name: reload nginx
service: name=nginx state=reloaded

4
devops/templates/bindctl Normal file
View File

@ -0,0 +1,4 @@
#
# Allow peach-dyndns to reload bind as sudo
#
peach-dyndns ALL=(ALL) NOPASSWD: /usr/bin/reloadbind

View File

@ -0,0 +1,14 @@
server {
listen 80;
listen [::]:80;
server_name {{dynserver_domain}};
location / {
proxy_pass http://127.0.0.1:{{dynserver_port}};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}

View File

@ -0,0 +1,10 @@
description "uWSGI server instance configured to serve hello_webapp"
start on runlevel [2345]
stop on runlevel [!2345]
setuid wsgi-user
setgid webgroup
chdir {{src_dir}}
exec uwsgi --ini hello_webapp.ini

View File

@ -0,0 +1,12 @@
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local
include "/etc/bind/named.conf.options";
include "/etc/bind/dyn.peachcloud.org.keys";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";

View File

@ -0,0 +1,86 @@
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}

View File

@ -0,0 +1,10 @@
server {
listen 80;
server_name ec2-52-90-110-188.compute-1.amazonaws.com;
location / {
include uwsgi_params;
uwsgi_pass unix:{{src_dir}}/{{app_name}}.sock;
}
}

View File

@ -0,0 +1,15 @@
[Unit]
Description=An http API to create dynamic-dns configurations for bind9.
[Service]
Type=simple
User=peach-dyndns
Group=bind
Environment="RUST_LOG=info"
Environment="PEACH_DYNDNS_SERVER=127.0.0.1:{{dynserver_port}}"
WorkingDirectory=/srv/peach-dynddns-server
ExecStart=/usr/bin/peach-dyndns-server
Restart=always
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
/bin/systemctl reload bind9

2
devops/vars.yaml Normal file
View File

@ -0,0 +1,2 @@
dynserver_domain: dynserver.commoninternet.net
dynserver_port: 3002

2
setup_server.sh Executable file
View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
ansible-playbook -i devops/hosts devops/setup_server.yml

View File

@ -100,14 +100,26 @@ pub fn generate_zone(full_domain: &str) -> Result<String, PeachDynDnsError> {
.append(true) .append(true)
.open(bind_conf_path) .open(bind_conf_path)
.unwrap_or_else(|_| panic!("failed to open {}", bind_conf_path)); .unwrap_or_else(|_| panic!("failed to open {}", bind_conf_path));
// this commented out section, with update-policy stopped working
// so we are now using allow-update
// let zone_section_text = format!(
// "\
// zone \"{full_domain}\" {{
// type master;
// file \"/var/lib/bind/{full_domain}\";
// update-policy {{
// grant {full_domain} self {full_domain};
// }};
// }};
// ",
// full_domain = full_domain
// );
let zone_section_text = format!( let zone_section_text = format!(
"\ "\
zone \"{full_domain}\" {{ zone \"{full_domain}\" {{
type master; type master;
file \"/var/lib/bind/{full_domain}\"; file \"/var/lib/bind/{full_domain}\";
update-policy {{ allow-update {{key \"{full_domain}\";}};
grant {full_domain} self {full_domain};
}};
}}; }};
", ",
full_domain = full_domain full_domain = full_domain

View File

@ -72,11 +72,9 @@ pub fn run() -> Result<(), BoxError> {
let http_server = let http_server =
env::var("PEACH_DYNDNS_SERVER").unwrap_or_else(|_| "127.0.0.1:3001".to_string()); env::var("PEACH_DYNDNS_SERVER").unwrap_or_else(|_| "127.0.0.1:3001".to_string());
info!("Starting JSON-RPC server on {}.", http_server); info!("Starting JSON-RPC server on {}", http_server);
let server = ServerBuilder::new(io) let server = ServerBuilder::new(io)
.cors(DomainsValidation::AllowOnly(vec![ .cors(DomainsValidation::Disabled)
AccessControlAllowOrigin::Null,
]))
.start_http( .start_http(
&http_server &http_server
.parse() .parse()