From 8cfcdfe9ed5e236167d9af706d47014d9c1cbd63 Mon Sep 17 00:00:00 2001 From: reid Date: Mon, 24 Oct 2022 17:26:54 -0500 Subject: [PATCH 01/26] fix PreDown forwarding rules --- .gitignore | 4 +--- api/np_db.py | 2 +- api/wg_api.py | 45 +++++++++++++++++++++++++++------------------ 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index db2aee1..77f2f06 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,2 @@ -wg-push -caddy-push -api-push +*-push key.pem \ No newline at end of file diff --git a/api/np_db.py b/api/np_db.py index 49e7d34..690fdb5 100644 --- a/api/np_db.py +++ b/api/np_db.py @@ -234,7 +234,7 @@ def rectify_svc_list(pubkey): forwarded = ['urbit-ames'] caddy_conf = caddy_api.get_conf()['apps']['http']['servers']['srv0']['routes'] svc_list, caddy_list = ['anchor'], [] - services, minios = {}, {} + services, minios, ameses = {}, {}, {} peerlist = wg_api.peer_list() del_peers = [] svcs = get_client_svcs(pubkey) diff --git a/api/wg_api.py b/api/wg_api.py index 6c417df..a81481f 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -34,6 +34,7 @@ def restart_wg(): resp = requests.get(url) if resp.status_code == 200: logging.info('[WG]: WG interface restarted') + fwd_predown_rules() return True else: logging.warn(f'[WG]: Could not restart WG: {resp.status_code}') @@ -203,23 +204,6 @@ def rule_gen(rule,ad): fwd = rule_gen('fwd','A') contents.insert(index, pre) contents.insert(index, fwd) - if (pre != False) and (fwd != False): - with open("/etc/wireguard/wg0.conf", "w") as f: - contents = "".join(contents) - f.write(contents) - else: - logging.warning(f'[WG]: Invalid routing rule') - return False - with open("/etc/wireguard/wg0.conf", "r") as f: - contents = f.readlines() - for num, line in enumerate(contents, 1): - # Find the line numbers to insert PreDown rules - if 'PostDown' in line: - index = num - 1 - pre = rule_gen('pre','D') - fwd = rule_gen('fwd','D') - contents.insert(index, pre) - contents.insert(index, fwd) if (pre != False) and (fwd != False): with open("/etc/wireguard/wg0.conf", "w") as f: contents = "".join(contents) @@ -308,4 +292,29 @@ def port_list(port_input): except Exception as e: print(e) logging.warn(f'[WG]: Port fwd rectification: {e}') - return False \ No newline at end of file + return False + +# Create PreDown rules after interface restart +# We can't restart it if it has an invalid rule +def fwd_predown_rules(): + pres = [] + f = open('/etc/wireguard/wg0.conf', 'r') + content = f.read().splitlines() + # Extract all forwarding PreUp rules + for line in content: + if ("--dport" in line) and ("PreUp" in line): + substr = "PreUp = iptables -A" + replace = "PreDown = iptables -D" + # Create matching PreDown rules + post_rule = line.replace(substr, replace) + pres.append(post_rule) + with open("/etc/wireguard/wg0.conf", "r") as f: + contents = f.readlines() + for num, line in enumerate(contents, 1): + # Find the line numbers to insert PreDown rules + if 'PostDown' in line: + index = num - 1 + for rule in pres: + # Append deletion rules if they don't exist + if rule not in content: + content.insert(index,rule) \ No newline at end of file From f55f9b1dceb5e8c2835b303e9ad68a4030387f93 Mon Sep 17 00:00:00 2001 From: reid Date: Wed, 26 Oct 2022 17:46:34 -0500 Subject: [PATCH 02/26] add delete endpoint --- api/app.py | 19 ++++++++++++++++ api/np_db.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/api/app.py b/api/app.py index f86a524..de9307e 100644 --- a/api/app.py +++ b/api/app.py @@ -164,6 +164,25 @@ def add_anchor(): response = np_db.invalid_fail(subdomain,pubkey,svc_type,validation) return jsonify(response) +# Route to delete a registered service +@app.route('/v1/delete', methods=['POST']) +def del_svc(): + + headers = request.headers + content = request.get_json() + fwd_ip = headers.get("X-Forwarded-For") + subdomain = content.get('subdomain').lower() + pubkey = content.get('pubkey') + svc_type = content.get('svc_type').lower() + timestamp = datetime.now() + + logging.info(f"\n\n===\n{timestamp}\n•{subdomain} {fwd_ip} DELETE\n---\n{content}\n---") + + response = np_db.delete_service(subdomain,pubkey,svc_type) + req_code = response['code'] + response.pop('code',None) + return jsonify(response),req_code + if __name__ == "__main__": http_server = WSGIServer(('0.0.0.0', 8090), app) diff --git a/api/np_db.py b/api/np_db.py index 690fdb5..3f00d00 100644 --- a/api/np_db.py +++ b/api/np_db.py @@ -449,6 +449,68 @@ def port_assign(svc): upd_value('services','status','creating','uid',svc) +# Delete a service for a client +def delete_service(subdomain,pubkey,svc_type): + lease = get_value('anchors','lease','pubkey',pubkey) + response = {'action':'delete', + 'debug':None, + 'error':0, + 'pubkey':pubkey, + 'svc_type':svc_type, + 'lease':lease, + 'subdomain':subdomain, + 'code':200} + sub_exists = get_value('services','uid','subdomain',subdomain) + pub_exists = get_value('services','pubkey','subdomain',subdomain) + if sub_exists != False: + if pubkey == pub_exists: + assoc_rows = [] + sub_svc = get_value('services','svc_type','uid',sub_exists) + if (sub_svc == 'urbit-web') or (sub_svc == 'urbit-ames'): + service = 'urbit' + assoc_rows.append(sub_exists) + if sub_svc == 'urbit-web': + ames_row = get_value('services','uid','subdomain',f'ames.{subdomain}') + assoc_rows.append(ames_row) + else: + landscape_sub = subdomain.replace('ames.','') + landscape_row = get_value('services','uid','subdomain',landscape_row) + assoc_rows.append(landscape_row) + elif (sub_svc == 'minio') or (sub_svc == 'minio-console') or (sub_svc == 'minio-bucket'): + service = 'minio' + assoc_rows.append(sub_exists) + if sub_svc == 'minio': + console_row = get_value('services','uid','subdomain',f'console.{subdomain}') + bucket_row = get_value('services','uid','subdomain',f'bucket.{subdomain}') + assoc_rows.append(console_row) + append_rows.append(bucket_row) + elif sub_svc == 'minio-console': + minio_sub = subdomain.replace('console.','') + minio_row = get_value('services','uid','subdomain',minio_sub) + bucket_row = get_value('services','uid','subdomain',f'bucket.{minio_sub}') + append_rows.append(minio_row) + append_rows.append(bucket_row) + elif sub_svc == 'minio-bucket': + minio_sub = subdomain.replace('bucket.','') + console_row = get_value('services','uid','subdomain',f'console.{minio_sub}') + minio_row = get_value('services','uid','subdomain',minio_sub) + append_rows.append(console_row) + append_rows.append(minio_row) + if assoc_rows != []: + for svc in assoc_rows: + delete_svc('uid',svc) + threading.Thread(target=rectify_svc_list, name='poll', args=(pubkey,)).start() + else: + response['error'] = 1 + response['code'] = 400 + response['debug'] = 'Invalid pubkey' + else: + response['error'] = 1 + response['code'] = 400 + response['debug'] = 'Service is not registered' + return response + + # Determine random unused port for service def port_gen(svc_type): port_records = get_values('services','port','svc_type',svc_type) From ab7fdaf70a5279e39919499bc4a4c54492e2ab2b Mon Sep 17 00:00:00 2001 From: reid Date: Wed, 2 Nov 2022 16:42:45 -0500 Subject: [PATCH 03/26] update /retrieve with ongoing bit --- api/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/api/app.py b/api/app.py index de9307e..64df226 100644 --- a/api/app.py +++ b/api/app.py @@ -127,6 +127,7 @@ def retrieve_info(): 'pubkey':pubkey, 'status':status, 'subdomains':subdomains, + 'ongoing':1, 'lease': np_db.lease} return jsonify(response),reqstatus From b0417e57bc2b2a7b192e289418db1af4f57db851 Mon Sep 17 00:00:00 2001 From: reid Date: Sun, 6 Nov 2022 10:16:03 -0600 Subject: [PATCH 04/26] fix port forwarding --- api/wg_api.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/api/wg_api.py b/api/wg_api.py index a81481f..f436649 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -223,7 +223,16 @@ def remove_fwd(port): new_f = f.readlines() f.seek(0) for line in new_f: - if lookup not in line: + if (lookup not in line) and ('PreUp' not in line): + f.write(line) + f.truncate() + # Restart after the PreUp rule is removed + # in order to be able to remove PreDown + restart_wg() + f.seek(0) + new_f = f.readlines() + for line in new_f: + if (lookup not in line) and ('PreDown' not in line): f.write(line) f.truncate() # You still need to restart the interface From abbda0a6b86ac1168dbe48eece83835f7209d306 Mon Sep 17 00:00:00 2001 From: reid Date: Sun, 6 Nov 2022 10:40:39 -0600 Subject: [PATCH 05/26] fix port forward removal --- api/wg_api.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/wg_api.py b/api/wg_api.py index f436649..d396a3e 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -219,6 +219,7 @@ def remove_fwd(port): port = str(port) logging.info(f'[WG]: Removing port forwarding for {port}') lookup = f'dport {port}' + # Remove the PreUp rule with open("/etc/wireguard/wg0.conf","r+") as f: new_f = f.readlines() f.seek(0) @@ -229,6 +230,8 @@ def remove_fwd(port): # Restart after the PreUp rule is removed # in order to be able to remove PreDown restart_wg() + # Remove the PreDown rule (no restart) + with open("/etc/wireguard/wg0.conf","r+") as f: f.seek(0) new_f = f.readlines() for line in new_f: @@ -317,7 +320,7 @@ def fwd_predown_rules(): # Create matching PreDown rules post_rule = line.replace(substr, replace) pres.append(post_rule) - with open("/etc/wireguard/wg0.conf", "r") as f: + with open("/etc/wireguard/wg0.conf", "r+") as f: contents = f.readlines() for num, line in enumerate(contents, 1): # Find the line numbers to insert PreDown rules From 85f1bc28165b30e749992c80a27e5caa18dcf1c0 Mon Sep 17 00:00:00 2001 From: reid Date: Sun, 6 Nov 2022 10:58:37 -0600 Subject: [PATCH 06/26] fix port forward removal --- api/wg_api.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/api/wg_api.py b/api/wg_api.py index d396a3e..a49a663 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -310,16 +310,15 @@ def port_list(port_input): # We can't restart it if it has an invalid rule def fwd_predown_rules(): pres = [] - f = open('/etc/wireguard/wg0.conf', 'r') - content = f.read().splitlines() - # Extract all forwarding PreUp rules - for line in content: - if ("--dport" in line) and ("PreUp" in line): - substr = "PreUp = iptables -A" - replace = "PreDown = iptables -D" - # Create matching PreDown rules - post_rule = line.replace(substr, replace) - pres.append(post_rule) + with open("/etc/wireguard/wg0.conf", "r") as f: + contents = f.readlines() + for num, line in enumerate(contents, 1): + if ("--dport" in line) and ("PreUp" in line): + substr = "PreUp = iptables -A" + replace = "PreDown = iptables -D" + # Create matching PreDown rules + post_rule = line.replace(substr,replace) + pres.append(post_rule) with open("/etc/wireguard/wg0.conf", "r+") as f: contents = f.readlines() for num, line in enumerate(contents, 1): @@ -329,4 +328,6 @@ def fwd_predown_rules(): for rule in pres: # Append deletion rules if they don't exist if rule not in content: - content.insert(index,rule) \ No newline at end of file + content.insert(index,rule) + pred = len(pres) + logging.info(f'[WG] Inserted {pred} PreDown rules') \ No newline at end of file From 7ca40552ac231d358911f87bd83fc4f6d4685547 Mon Sep 17 00:00:00 2001 From: reid Date: Sun, 6 Nov 2022 10:59:31 -0600 Subject: [PATCH 07/26] fix port forward removal --- api/wg_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/wg_api.py b/api/wg_api.py index a49a663..acfcc86 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -327,7 +327,7 @@ def fwd_predown_rules(): index = num - 1 for rule in pres: # Append deletion rules if they don't exist - if rule not in content: - content.insert(index,rule) + if rule not in contents: + contents.insert(index,rule) pred = len(pres) logging.info(f'[WG] Inserted {pred} PreDown rules') \ No newline at end of file From 8959da5f492e992b5ce67d7279173a0881681bba Mon Sep 17 00:00:00 2001 From: reid Date: Sun, 6 Nov 2022 11:05:56 -0600 Subject: [PATCH 08/26] fix port forward removal --- api/wg_api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/api/wg_api.py b/api/wg_api.py index acfcc86..956a4e2 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -329,5 +329,6 @@ def fwd_predown_rules(): # Append deletion rules if they don't exist if rule not in contents: contents.insert(index,rule) + f.write(contents) pred = len(pres) logging.info(f'[WG] Inserted {pred} PreDown rules') \ No newline at end of file From 222f0669f8c6bcd3a16f48a92911183ece0a0482 Mon Sep 17 00:00:00 2001 From: reid Date: Sun, 6 Nov 2022 11:09:28 -0600 Subject: [PATCH 09/26] fix port forward removal --- api/wg_api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/api/wg_api.py b/api/wg_api.py index 956a4e2..9084c67 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -329,6 +329,7 @@ def fwd_predown_rules(): # Append deletion rules if they don't exist if rule not in contents: contents.insert(index,rule) + contents = "".join(contents) f.write(contents) pred = len(pres) logging.info(f'[WG] Inserted {pred} PreDown rules') \ No newline at end of file From 3bb5f1f12c174f9d331dbf1b7d0309308a03408d Mon Sep 17 00:00:00 2001 From: reid Date: Sun, 6 Nov 2022 11:16:30 -0600 Subject: [PATCH 10/26] fix port forward removal --- api/wg_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/wg_api.py b/api/wg_api.py index 9084c67..8185cf4 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -329,7 +329,7 @@ def fwd_predown_rules(): # Append deletion rules if they don't exist if rule not in contents: contents.insert(index,rule) - contents = "".join(contents) + contents = str("".join(contents)) f.write(contents) pred = len(pres) logging.info(f'[WG] Inserted {pred} PreDown rules') \ No newline at end of file From e12a69e5836eb9c955b477a5430cd9e8f27e19bf Mon Sep 17 00:00:00 2001 From: reid Date: Sun, 6 Nov 2022 11:40:59 -0600 Subject: [PATCH 11/26] fix port forward removal & webhook max concurrency --- api/wg_api.py | 11 ++++++++--- wg/hooks.json | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/api/wg_api.py b/api/wg_api.py index 8185cf4..7957bf8 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -36,6 +36,9 @@ def restart_wg(): logging.info('[WG]: WG interface restarted') fwd_predown_rules() return True + elif resp.status_code == 429: + logging.info('[WG]: WG interface already restarting!') + return False else: logging.warn(f'[WG]: Could not restart WG: {resp.status_code}') return False @@ -310,7 +313,7 @@ def port_list(port_input): # We can't restart it if it has an invalid rule def fwd_predown_rules(): pres = [] - with open("/etc/wireguard/wg0.conf", "r") as f: + with open("/etc/wireguard/wg0.conf", "w") as f: contents = f.readlines() for num, line in enumerate(contents, 1): if ("--dport" in line) and ("PreUp" in line): @@ -320,6 +323,7 @@ def fwd_predown_rules(): post_rule = line.replace(substr,replace) pres.append(post_rule) with open("/etc/wireguard/wg0.conf", "r+") as f: + f.seek(0) contents = f.readlines() for num, line in enumerate(contents, 1): # Find the line numbers to insert PreDown rules @@ -329,7 +333,8 @@ def fwd_predown_rules(): # Append deletion rules if they don't exist if rule not in contents: contents.insert(index,rule) - contents = str("".join(contents)) - f.write(contents) + contents = "".join(contents) + with open("/etc/wireguard/wg0.conf", "w") as f: + f.write(str(contents)) pred = len(pres) logging.info(f'[WG] Inserted {pred} PreDown rules') \ No newline at end of file diff --git a/wg/hooks.json b/wg/hooks.json index d19a689..e7f1b02 100644 --- a/wg/hooks.json +++ b/wg/hooks.json @@ -3,6 +3,7 @@ "id": "restart-wg", "execute-command": "/etc/webhook/restart.sh", "response-message": "Success -- interface restarting", + "max-concurrency": 1, "trigger-rule": { "or": From 72f13cb416d1ec0bfa720b3271c28b08d90b2d25 Mon Sep 17 00:00:00 2001 From: reid Date: Thu, 10 Nov 2022 10:28:04 -0600 Subject: [PATCH 12/26] fix port fwd removal --- api/wg_api.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api/wg_api.py b/api/wg_api.py index 7957bf8..2959305 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -223,7 +223,7 @@ def remove_fwd(port): logging.info(f'[WG]: Removing port forwarding for {port}') lookup = f'dport {port}' # Remove the PreUp rule - with open("/etc/wireguard/wg0.conf","r+") as f: + with open("/etc/wireguard/wg0.conf","w+") as f: new_f = f.readlines() f.seek(0) for line in new_f: @@ -234,7 +234,7 @@ def remove_fwd(port): # in order to be able to remove PreDown restart_wg() # Remove the PreDown rule (no restart) - with open("/etc/wireguard/wg0.conf","r+") as f: + with open("/etc/wireguard/wg0.conf","w+") as f: f.seek(0) new_f = f.readlines() for line in new_f: @@ -313,7 +313,7 @@ def port_list(port_input): # We can't restart it if it has an invalid rule def fwd_predown_rules(): pres = [] - with open("/etc/wireguard/wg0.conf", "w") as f: + with open("/etc/wireguard/wg0.conf", "w+") as f: contents = f.readlines() for num, line in enumerate(contents, 1): if ("--dport" in line) and ("PreUp" in line): @@ -322,7 +322,7 @@ def fwd_predown_rules(): # Create matching PreDown rules post_rule = line.replace(substr,replace) pres.append(post_rule) - with open("/etc/wireguard/wg0.conf", "r+") as f: + with open("/etc/wireguard/wg0.conf", "w+") as f: f.seek(0) contents = f.readlines() for num, line in enumerate(contents, 1): @@ -334,7 +334,7 @@ def fwd_predown_rules(): if rule not in contents: contents.insert(index,rule) contents = "".join(contents) - with open("/etc/wireguard/wg0.conf", "w") as f: + with open("/etc/wireguard/wg0.conf", "w+") as f: f.write(str(contents)) pred = len(pres) logging.info(f'[WG] Inserted {pred} PreDown rules') \ No newline at end of file From 6a4291e29efc2830358ceb394f8f50fca419d8b8 Mon Sep 17 00:00:00 2001 From: reid Date: Fri, 11 Nov 2022 17:13:22 -0600 Subject: [PATCH 13/26] fix remove_fwd() --- api/wg_api.py | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/api/wg_api.py b/api/wg_api.py index 2959305..58134af 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -220,28 +220,30 @@ def rule_gen(rule,ad): # Remove a forwarding rule from WG conf def remove_fwd(port): port = str(port) - logging.info(f'[WG]: Removing port forwarding for {port}') - lookup = f'dport {port}' + lookup = f'--dport {port}' # Remove the PreUp rule - with open("/etc/wireguard/wg0.conf","w+") as f: - new_f = f.readlines() - f.seek(0) - for line in new_f: - if (lookup not in line) and ('PreUp' not in line): + linematch,preups,predowns = [],[],[] + with open(wgconf, "r") as f: + lines = f.readlines() + for line in lines: + if lookup in line: + linematch.append(lines.index(line)) + preups = linematch[0:2] + predowns = linematch[2:4] + with open(wgconf, 'w') as f: + for number, line in enumerate(lines): + if number not in preups: f.write(line) - f.truncate() - # Restart after the PreUp rule is removed - # in order to be able to remove PreDown - restart_wg() + # Restart after the PreUp rule is removed + # in order to be able to remove PreDown + restart_wg() # Remove the PreDown rule (no restart) - with open("/etc/wireguard/wg0.conf","w+") as f: - f.seek(0) - new_f = f.readlines() - for line in new_f: - if (lookup not in line) and ('PreDown' not in line): + with open(wgconf, "r") as f: + lines = f.readlines() + with open(wgconf, 'w') as f: + for number, line in enumerate(lines): + if number not in predowns: f.write(line) - f.truncate() - # You still need to restart the interface # Return a dict of all existing port forwards # {tcp:{port:peer,port:peer},udp:{port:peer}} From eb8d1fb912180409e45914a304c1f32ba3be470c Mon Sep 17 00:00:00 2001 From: reid Date: Mon, 14 Nov 2022 21:13:25 -0600 Subject: [PATCH 14/26] fix wg functions --- api/np_db.py | 4 ++++ api/wg_api.py | 46 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/api/np_db.py b/api/np_db.py index 3f00d00..8916957 100644 --- a/api/np_db.py +++ b/api/np_db.py @@ -171,6 +171,10 @@ def check_dns(url): my_ip = get('https://api.ipify.org').content.decode('utf8') subdomain_ip = socket.gethostbyname(url) if subdomain_ip != my_ip: + print(f'''[DNS]\n + Error: please double-check your DNS records!\n + Your host: {my_ip}\n + {url} IP: {subdomain_ip}''') return False else: return True diff --git a/api/wg_api.py b/api/wg_api.py index 58134af..60e1f5e 100644 --- a/api/wg_api.py +++ b/api/wg_api.py @@ -28,19 +28,27 @@ def wg_pubkey(): srv_pubkey = wg_pubkey() # Reset interface +# Restart with preup list, insert predown rules, restart again, remove predown def restart_wg(): + logging.info('[WG]: Restarting interface...') hook_auth = os.getenv('HOOK_AUTH') url = f"http://172.20.0.2:9000/hooks/restart-wg?token={hook_auth}" - resp = requests.get(url) + try: + resp = requests.get(url) + msg = resp.content.decode('utf-8') + except Exception as e: + logging.error(f'[WG]: Failed to parse response from webhook {e}') + return False if resp.status_code == 200: logging.info('[WG]: WG interface restarted') + remove_predowns() fwd_predown_rules() + os.system(f'cp {wgconf} {wgconf}.bak') return True - elif resp.status_code == 429: - logging.info('[WG]: WG interface already restarting!') - return False else: - logging.warn(f'[WG]: Could not restart WG: {resp.status_code}') + title = f'{hosturl} Could not restart IF' + logging.error(f'[WG]: Could not restart WG: {msg}') + sg_api.send_email(title,msg) return False # Does this pubkey exist? @@ -315,7 +323,7 @@ def port_list(port_input): # We can't restart it if it has an invalid rule def fwd_predown_rules(): pres = [] - with open("/etc/wireguard/wg0.conf", "w+") as f: + with open(wgconf, "r") as f: contents = f.readlines() for num, line in enumerate(contents, 1): if ("--dport" in line) and ("PreUp" in line): @@ -323,9 +331,11 @@ def fwd_predown_rules(): replace = "PreDown = iptables -D" # Create matching PreDown rules post_rule = line.replace(substr,replace) + # Ignore this in stdout in case it's an unapplied rule + if '&' not in post_rule: + post_rule = post_rule.replace('\n',' &\n') pres.append(post_rule) - with open("/etc/wireguard/wg0.conf", "w+") as f: - f.seek(0) + with open(wgconf, "r") as f: contents = f.readlines() for num, line in enumerate(contents, 1): # Find the line numbers to insert PreDown rules @@ -336,7 +346,23 @@ def fwd_predown_rules(): if rule not in contents: contents.insert(index,rule) contents = "".join(contents) - with open("/etc/wireguard/wg0.conf", "w+") as f: + with open(wgconf, "w+") as f: f.write(str(contents)) + logging.info(f'fwd_predown_rules(): {contents}') pred = len(pres) - logging.info(f'[WG] Inserted {pred} PreDown rules') \ No newline at end of file + logging.info(f'[WG]: Inserted {pred} PreDown rules') + +# Remove all predown rules (for restart_wg) +def remove_predowns(): + with open(wgconf, "r") as f: + lines = f.readlines() + count,keep = 0,[] + for num,line in enumerate(lines): + if 'PreDown' not in line: + keep.append(num) + count += 1 + with open(wgconf, 'w') as f: + for num,line in enumerate(lines): + if num in keep: + f.write(line) + return True \ No newline at end of file From b42905691de67595b36a85aa7627ef88da2bfa90 Mon Sep 17 00:00:00 2001 From: reid Date: Tue, 15 Nov 2022 21:34:04 -0600 Subject: [PATCH 15/26] add build pipeline --- Jenkinsfile | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..737a73e --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,71 @@ +pipeline { + agent any + environment { + reg_pw = credentials('Dockerhub PW') + environ = sh ( + script: ''' + echo $BRANCH_NAME|sed 's@origin/@@g' + ''', + returnStdout: true + ).trim() + } + stages { + stage('Build') { + environment { + environ = sh ( + script: ''' + echo $BRANCH_NAME|sed 's@origin/@@g' + ''', + returnStdout: true + ).trim() + tag = sh ( + script: ''' + if [ "${environ}" = "dev" ]; then + echo "staging" + elif [ "${environ}" = "master" ]; then + echo "latest" + else + echo "nobuild" + fi + ''', + returnStdout: true + ).trim() + } + steps { + script { + if( "${tag}" == "nobuild" ) { + currentBuild.getRawBuild().getExecutor().interrupt(Result.NOT_BUILT) + print("Ignoring branch ${tag}") + sleep(1) + } + } + git url: 'https://github.com/Native-Planet/startram.git', + credentialsId: 'Github token', + branch: "${environ}" + sh "docker login -u np -p $reg_pw img.infra.native.computer" + dir("${env.WORKSPACE}/"){ + sh ( + script: ''' + docker login -u nativeplanet -p ${DH_PW} docker.io + docker buildx build --platform linux/amd64 --no-cache ./api/ -t anchor-api:${tag} + docker tag anchor-api:${tag} nativeplanet/anchor-api:${tag} + docker buildx build --platform linux/amd64 --no-cache ./wg/ -t anchor-wg:${tag} + docker tag anchor-wg:${tag} nativeplanet/anchor-wg:${tag} + docker buildx build --platform linux/amd64 --no-cache ./caddy/ -t anchor-caddy:${tag} + docker tag anchor-caddy:${tag} nativeplanet/anchor-caddy:${tag} + docker push nativeplanet/anchor-api:${tag} + docker push nativeplanet/anchor-wg:${tag} + docker push nativeplanet/anchor-caddy:${tag} + ''', + returnStdout: true + ) + } + } + } + } + post { + always { + cleanWs deleteDirs: true, notFailBuild: true + } + } +} \ No newline at end of file From 2a2f81971bef229d2b35d8f8f16f6c231bae9707 Mon Sep 17 00:00:00 2001 From: reid Date: Tue, 15 Nov 2022 21:36:15 -0600 Subject: [PATCH 16/26] add build pipeline --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 737a73e..9280892 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -39,7 +39,7 @@ pipeline { sleep(1) } } - git url: 'https://github.com/Native-Planet/startram.git', + git url: 'https://github.com/Native-Planet/anchor-source.git', credentialsId: 'Github token', branch: "${environ}" sh "docker login -u np -p $reg_pw img.infra.native.computer" From c6e407b300e7b1ebfd525748e9ed24c066511bea Mon Sep 17 00:00:00 2001 From: reid Date: Tue, 15 Nov 2022 21:37:14 -0600 Subject: [PATCH 17/26] add build pipeline --- Jenkinsfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 9280892..783ba82 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -42,11 +42,10 @@ pipeline { git url: 'https://github.com/Native-Planet/anchor-source.git', credentialsId: 'Github token', branch: "${environ}" - sh "docker login -u np -p $reg_pw img.infra.native.computer" + sh "docker login -u nativeplanet -p $reg_pw docker.io" dir("${env.WORKSPACE}/"){ sh ( script: ''' - docker login -u nativeplanet -p ${DH_PW} docker.io docker buildx build --platform linux/amd64 --no-cache ./api/ -t anchor-api:${tag} docker tag anchor-api:${tag} nativeplanet/anchor-api:${tag} docker buildx build --platform linux/amd64 --no-cache ./wg/ -t anchor-wg:${tag} From f5984699b03ce185f05a6e2659aaf14a28338c92 Mon Sep 17 00:00:00 2001 From: reid Date: Tue, 15 Nov 2022 22:01:20 -0600 Subject: [PATCH 18/26] add branch checking --- Jenkinsfile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 783ba82..bcb8069 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -32,6 +32,13 @@ pipeline { ).trim() } steps { + script { + if( "${tag}" == "nobuild" ) { + currentBuild.getRawBuild().getExecutor().interrupt(Result.NOT_BUILT) + print("Ignoring branch ${tag}") + sleep(1) + } + } script { if( "${tag}" == "nobuild" ) { currentBuild.getRawBuild().getExecutor().interrupt(Result.NOT_BUILT) From bbfadeb99d419bf81d19832baa839b7b87f21b9f Mon Sep 17 00:00:00 2001 From: reid Date: Tue, 15 Nov 2022 22:12:56 -0600 Subject: [PATCH 19/26] change status for ignored branch/pr to aborted --- Jenkinsfile | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index bcb8069..fd964ba 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -34,14 +34,7 @@ pipeline { steps { script { if( "${tag}" == "nobuild" ) { - currentBuild.getRawBuild().getExecutor().interrupt(Result.NOT_BUILT) - print("Ignoring branch ${tag}") - sleep(1) - } - } - script { - if( "${tag}" == "nobuild" ) { - currentBuild.getRawBuild().getExecutor().interrupt(Result.NOT_BUILT) + currentBuild.getRawBuild().getExecutor().interrupt(Result.ABORTED) print("Ignoring branch ${tag}") sleep(1) } From e78c6c05771831d13ae226639363bf0d9ad8c23c Mon Sep 17 00:00:00 2001 From: reid Date: Tue, 22 Nov 2022 14:02:16 -0600 Subject: [PATCH 20/26] add nuitka build --- Jenkinsfile | 2 +- api/Nuitka.dockerfile | 17 +++++++++++++++++ api/caddy_api.py | 4 +--- 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 api/Nuitka.dockerfile diff --git a/Jenkinsfile b/Jenkinsfile index fd964ba..b9a7dfd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -46,7 +46,7 @@ pipeline { dir("${env.WORKSPACE}/"){ sh ( script: ''' - docker buildx build --platform linux/amd64 --no-cache ./api/ -t anchor-api:${tag} + docker buildx build --platform linux/amd64 --no-cache ./api/ -f Nuitka.dockerfile -t anchor-api:${tag} docker tag anchor-api:${tag} nativeplanet/anchor-api:${tag} docker buildx build --platform linux/amd64 --no-cache ./wg/ -t anchor-wg:${tag} docker tag anchor-wg:${tag} nativeplanet/anchor-wg:${tag} diff --git a/api/Nuitka.dockerfile b/api/Nuitka.dockerfile new file mode 100644 index 0000000..0eb8292 --- /dev/null +++ b/api/Nuitka.dockerfile @@ -0,0 +1,17 @@ +FROM alpine:3.17 AS builder +RUN mkdir /app +WORKDIR /app +# Install dependencies: +RUN apk update && apk add --update musl-dev gcc patchelf python3-dev py3-pip chrpath wget make ccache +RUN pip install nuitka zstandard wheel +COPY requirements.txt /app/requirements.txt +RUN pip install -r /app/requirements.txt + +# Build +COPY ./ /app +RUN python3 -m nuitka --onefile app.py + +# Clean layer +FROM alpine:3.17 +COPY --from=builder /app/app.bin /app/anchor +CMD ["./app/anchor"] \ No newline at end of file diff --git a/api/caddy_api.py b/api/caddy_api.py index eed47f6..60f2237 100644 --- a/api/caddy_api.py +++ b/api/caddy_api.py @@ -151,9 +151,7 @@ def check_upstream(sub,upstream): # If it's pointing at the right upstream return True else: - result = False - else: - result = False + return False except Exception as e: logging.exception(f'check_upstream: {sub} {upstream} {e}') return result From f828922ecc2a420f63125e8c45e060ef2a839cec Mon Sep 17 00:00:00 2001 From: reid Date: Tue, 22 Nov 2022 14:09:34 -0600 Subject: [PATCH 21/26] add nuitka build --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index b9a7dfd..ede0a3d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -46,7 +46,7 @@ pipeline { dir("${env.WORKSPACE}/"){ sh ( script: ''' - docker buildx build --platform linux/amd64 --no-cache ./api/ -f Nuitka.dockerfile -t anchor-api:${tag} + docker buildx build --platform linux/amd64 --no-cache ./api/ -f ./api/Nuitka.dockerfile -t anchor-api:${tag} docker tag anchor-api:${tag} nativeplanet/anchor-api:${tag} docker buildx build --platform linux/amd64 --no-cache ./wg/ -t anchor-wg:${tag} docker tag anchor-wg:${tag} nativeplanet/anchor-wg:${tag} From 68569b51900cbd070c96f0817bc7984a14552e4b Mon Sep 17 00:00:00 2001 From: reid Date: Tue, 22 Nov 2022 15:31:27 -0600 Subject: [PATCH 22/26] add nuitka build --- Jenkinsfile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ede0a3d..ff95d6f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -46,12 +46,9 @@ pipeline { dir("${env.WORKSPACE}/"){ sh ( script: ''' - docker buildx build --platform linux/amd64 --no-cache ./api/ -f ./api/Nuitka.dockerfile -t anchor-api:${tag} - docker tag anchor-api:${tag} nativeplanet/anchor-api:${tag} - docker buildx build --platform linux/amd64 --no-cache ./wg/ -t anchor-wg:${tag} - docker tag anchor-wg:${tag} nativeplanet/anchor-wg:${tag} - docker buildx build --platform linux/amd64 --no-cache ./caddy/ -t anchor-caddy:${tag} - docker tag anchor-caddy:${tag} nativeplanet/anchor-caddy:${tag} + docker buildx build --platform linux/amd64 --no-cache ./api/ -f ./api/Nuitka.dockerfile -t nativeplanet/anchor-api:${tag} + docker buildx build --platform linux/amd64 --no-cache ./wg/ -t nativeplanet/anchor-wg:${tag} + docker buildx build --platform linux/amd64 --no-cache ./caddy/ -t nativeplanet/anchor-caddy:${tag} docker push nativeplanet/anchor-api:${tag} docker push nativeplanet/anchor-wg:${tag} docker push nativeplanet/anchor-caddy:${tag} From a2e99e632017bf1d495f7466d45d7c631d00cd31 Mon Sep 17 00:00:00 2001 From: reid Date: Tue, 22 Nov 2022 17:23:52 -0600 Subject: [PATCH 23/26] fix buildx push --- Jenkinsfile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ff95d6f..b30cff7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -46,12 +46,9 @@ pipeline { dir("${env.WORKSPACE}/"){ sh ( script: ''' - docker buildx build --platform linux/amd64 --no-cache ./api/ -f ./api/Nuitka.dockerfile -t nativeplanet/anchor-api:${tag} - docker buildx build --platform linux/amd64 --no-cache ./wg/ -t nativeplanet/anchor-wg:${tag} - docker buildx build --platform linux/amd64 --no-cache ./caddy/ -t nativeplanet/anchor-caddy:${tag} - docker push nativeplanet/anchor-api:${tag} - docker push nativeplanet/anchor-wg:${tag} - docker push nativeplanet/anchor-caddy:${tag} + docker buildx build --push --tag nativeplanet/anchor-api:${tag} --platform linux/amd64 --no-cache ./api/ -f ./api/Nuitka.dockerfile + docker buildx build --push --tag nativeplanet/anchor-wg:${tag} --platform linux/amd64 --no-cache ./wg/ + docker buildx build --push --tag nativeplanet/anchor-caddy:${tag} --tag --platform linux/amd64 --no-cache ./caddy/ ''', returnStdout: true ) From e0c16b7b899aecc7503bb556ae9e87d5aee1f79c Mon Sep 17 00:00:00 2001 From: reid Date: Wed, 23 Nov 2022 07:14:09 -0600 Subject: [PATCH 24/26] fix buildx push --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index b30cff7..7a0007e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -48,7 +48,7 @@ pipeline { script: ''' docker buildx build --push --tag nativeplanet/anchor-api:${tag} --platform linux/amd64 --no-cache ./api/ -f ./api/Nuitka.dockerfile docker buildx build --push --tag nativeplanet/anchor-wg:${tag} --platform linux/amd64 --no-cache ./wg/ - docker buildx build --push --tag nativeplanet/anchor-caddy:${tag} --tag --platform linux/amd64 --no-cache ./caddy/ + docker buildx build --push --tag nativeplanet/anchor-caddy:${tag} --platform linux/amd64 --no-cache ./caddy/ ''', returnStdout: true ) From a76308763c5398f3aca5e13ef7079ed4d3178faf Mon Sep 17 00:00:00 2001 From: reid Date: Thu, 24 Nov 2022 19:38:43 -0600 Subject: [PATCH 25/26] disable nuitka build --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 7a0007e..2cdd9be 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -46,7 +46,7 @@ pipeline { dir("${env.WORKSPACE}/"){ sh ( script: ''' - docker buildx build --push --tag nativeplanet/anchor-api:${tag} --platform linux/amd64 --no-cache ./api/ -f ./api/Nuitka.dockerfile + docker buildx build --push --tag nativeplanet/anchor-api:${tag} --platform linux/amd64 --no-cache ./api/ docker buildx build --push --tag nativeplanet/anchor-wg:${tag} --platform linux/amd64 --no-cache ./wg/ docker buildx build --push --tag nativeplanet/anchor-caddy:${tag} --platform linux/amd64 --no-cache ./caddy/ ''', From 131b7eab377ab9084b1c50a92b4f055dcc0af0fa Mon Sep 17 00:00:00 2001 From: reid Date: Thu, 24 Nov 2022 19:40:55 -0600 Subject: [PATCH 26/26] use pinned caddy version, add cf dns --- api/np_db.py | 2 -- caddy/Dockerfile | 24 +++++++----------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/api/np_db.py b/api/np_db.py index 8916957..e41ec5d 100644 --- a/api/np_db.py +++ b/api/np_db.py @@ -297,7 +297,6 @@ def rectify_svc_list(pubkey): upstr = services[subd] if caddy_api.check_upstream(subd,upstr) == False: caddy_api.add_reverse_proxy(subd, host=f'{root_domain}',upstream=upstr) - sleep(3) # Delete pubkeys that aren't registered for peer in peerlist: @@ -311,7 +310,6 @@ def rectify_svc_list(pubkey): upstr = minios[subd] if caddy_api.check_upstream(subd,upstr) == False: caddy_api.add_minio(subd, host=f'{root_domain}',upstream=upstr) - sleep(3) # Rectify port forwarding configurations # Add a 'tcp' key for TCP services diff --git a/caddy/Dockerfile b/caddy/Dockerfile index 53a047f..2f2bc96 100644 --- a/caddy/Dockerfile +++ b/caddy/Dockerfile @@ -1,23 +1,13 @@ -# Build Caddy from master until 2.6 release -FROM golang:1.19.1-alpine3.16 as builder -WORKDIR / -RUN apk add --no-cache git -RUN git clone https://github.com/caddyserver/caddy.git -WORKDIR /caddy/cmd/caddy/ -RUN go build - -FROM caddy:2-alpine -WORKDIR / -RUN rm /usr/bin/caddy -COPY --from=builder /caddy/cmd/caddy/caddy /usr/bin/caddy -RUN chmod +x /usr/bin/caddy -RUN apk add --no-cache libcap curl -RUN setcap 'cap_net_bind_service=+ep' /usr/bin/caddy +FROM caddy:2.6.2-builder-alpine@sha256:735ad7b9a5ba5baf3df5f93034af5fa90c3554da9725d260df238d2511be6b23 AS builder +RUN xcaddy build \ + --with github.com/caddy-dns/cloudflare@latest +FROM caddy:2.6-alpine@sha256:7992b931b7da3cf0840dd69ea74b2c67d423faf03408da8abdc31b7590a239a7 +COPY --from=builder /usr/bin/caddy /usr/bin/caddy COPY ./default_config.json /etc/caddy/ -COPY ./www/502.html /www/ +RUN apk add curl RUN echo "#!/bin/ash" > /init RUN echo "ip route add 10.13.13.0/24 via 172.20.0.2" >> /init -RUN echo "exec caddy run --config /etc/caddy/default_config.json --resume" >> /init +RUN echo "exec /usr/bin/caddy run --config /etc/caddy/default_config.json --resume" >> /init RUN chmod +x /init EXPOSE 80 EXPOSE 443