[GH-ISSUE #683] Export letsencrypt certificates #578

Closed
opened 2026-02-26 06:33:30 +03:00 by kerem · 14 comments
Owner

Originally created by @dgeordgy21 on GitHub (Nov 2, 2020).
Original GitHub issue: https://github.com/NginxProxyManager/nginx-proxy-manager/issues/683

Hello,
Can you add a link to download each certificate generated by letsencrypt? It's usefull to put it in adguard for exemple DNS-over-TLS.
privkey.pem : the private key for your certificate.
fullchain.pem: the certificate file used in most server software.

Thes files are located in letsencrypt/live/npm-XX/

Thank you in advance.

Originally created by @dgeordgy21 on GitHub (Nov 2, 2020). Original GitHub issue: https://github.com/NginxProxyManager/nginx-proxy-manager/issues/683 Hello, Can you add a link to download each certificate generated by letsencrypt? It's usefull to put it in adguard for exemple DNS-over-TLS. `privkey.pem` : the private key for your certificate. `fullchain.pem`: the certificate file used in most server software. Thes files are located in letsencrypt/live/npm-XX/ Thank you in advance.
kerem 2026-02-26 06:33:30 +03:00
Author
Owner

@samborambo commented on GitHub (Nov 12, 2020):

I would also like to be able to link to the cert folder based on the site name. Its useful for npm to handle renewal for certs for services other than web.

I can see where the numbered folders map to but having site name folders would ease configuration. Also concerned numbering may change, breaking cert paths.

<!-- gh-comment-id:726072579 --> @samborambo commented on GitHub (Nov 12, 2020): I would also like to be able to link to the cert folder based on the site name. Its useful for npm to handle renewal for certs for services other than web. I can see where the numbered folders map to but having site name folders would ease configuration. Also concerned numbering may change, breaking cert paths.
Author
Owner

@Salamafet commented on GitHub (Dec 7, 2020):

Same here.

I use NPM on my Synology. I need to import the generate certificate for use it with Drive Client (desktop app).
The Drive App is not using a web protocol.

<!-- gh-comment-id:739745252 --> @Salamafet commented on GitHub (Dec 7, 2020): Same here. I use NPM on my Synology. I need to import the generate certificate for use it with Drive Client (desktop app). The Drive App is not using a web protocol.
Author
Owner

@coronas2k commented on GitHub (Dec 13, 2020):

First of all great project, really top-notch!

This feature would be helpful, as I'm using wildcard certs which I wish I could export from the UI.

Meanwhile, anyone using the docker image can copy the files from the container to the host with the following commands:

docker cp NPM_CONTAINER_ID:/etc/letsencrypt/archive/npm-X ./

Replace NPM_CONTAINER_ID with your container id, find it by running docker ps
Replace X with the order of the certificate, in my case I have one domain so it's 1

Example:
docker cp nginx_proxy_app_1:/etc/letsencrypt/archive/npm-1 ./

This will copy the certs from the container to the current working directory.

<!-- gh-comment-id:744028980 --> @coronas2k commented on GitHub (Dec 13, 2020): First of all great project, really top-notch! This feature would be helpful, as I'm using wildcard certs which I wish I could export from the UI. Meanwhile, anyone using the docker image can copy the files from the container to the host with the following commands: `docker cp NPM_CONTAINER_ID:/etc/letsencrypt/archive/npm-X ./` Replace NPM_CONTAINER_ID with your container id, find it by running _docker ps_ Replace X with the order of the certificate, in my case I have one domain so it's 1 Example: `docker cp nginx_proxy_app_1:/etc/letsencrypt/archive/npm-1 ./` This will copy the certs from the container to the current working directory.
Author
Owner

@cromulus commented on GitHub (Mar 17, 2021):

If you have many sites and many ssl certs, it's difficult to discern which npm-[0-9]* folder contains the certificates you want.

I iterate through the nom folders and run openssl x509 -noout -subject -in cert.pem but it's sub-optimal.

<!-- gh-comment-id:801464539 --> @cromulus commented on GitHub (Mar 17, 2021): If you have many sites and many ssl certs, it's difficult to discern which npm-[0-9]* folder contains the certificates you want. I iterate through the nom folders and run `openssl x509 -noout -subject -in cert.pem` but it's sub-optimal.
Author
Owner

@chaptergy commented on GitHub (May 12, 2021):

Duplicate of https://github.com/jc21/nginx-proxy-manager/issues/404

<!-- gh-comment-id:840061646 --> @chaptergy commented on GitHub (May 12, 2021): Duplicate of https://github.com/jc21/nginx-proxy-manager/issues/404
Author
Owner

@Qaezar commented on GitHub (Aug 12, 2021):

+1, would love this too ! ;)

Thank you ^^

<!-- gh-comment-id:897707521 --> @Qaezar commented on GitHub (Aug 12, 2021): +1, would love this too ! ;) Thank you ^^
Author
Owner

@samborambo commented on GitHub (Aug 12, 2021):

I solved this with a python script to copy out the certs to named folders. Not very well tested.

https://pastebin.com/gfAu5X8B

<!-- gh-comment-id:898018243 --> @samborambo commented on GitHub (Aug 12, 2021): I solved this with a python script to copy out the certs to named folders. Not very well tested. [https://pastebin.com/gfAu5X8B](url)
Author
Owner

@marrobHD commented on GitHub (Feb 13, 2022):

I would also like to see this. I need to copy the SSL certificates over to mailcows SSL folder.
A better cert folder naming would be useful for building a script that does what I need.
Until now I'm turning off SSL on npm for the mailcow domains when the SSL certs run out. I run certbot on mailcows side and add ssl back to npm mailcow domains.

<!-- gh-comment-id:1038451338 --> @marrobHD commented on GitHub (Feb 13, 2022): I would also like to see this. I need to copy the SSL certificates over to mailcows SSL folder. A better cert folder naming would be useful for building a script that does what I need. Until now I'm turning off SSL on npm for the mailcow domains when the SSL certs run out. I run certbot on mailcows side and add ssl back to npm mailcow domains.
Author
Owner

@captainabloc commented on GitHub (Feb 26, 2022):

Hi all,
here a small script for retrieving latest Fullchain and Privatekey from NPM.
Usefull for example for Adguardhome certificates renewal:

#!/bin/bash


# ----------------------------------
# Colors
# ----------------------------------
NOCOLOR='\033[0m'
RED='\033[0;31m'
GREEN='\033[0;32m'
ORANGE='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
LIGHTGRAY='\033[0;37m'
DARKGRAY='\033[1;30m'
LIGHTRED='\033[1;31m'
LIGHTGREEN='\033[1;32m'
YELLOW='\033[1;33m'
LIGHTBLUE='\033[1;34m'
LIGHTPURPLE='\033[1;35m'
LIGHTCYAN='\033[1;36m'
WHITE='\033[1;37m'

echo -e "${YELLOW}\n
1       abc.xyz
5       a.abc.xyz
6       b.abc.xyz
7       c.abc.xyz
8       d.abc.xyz
9       e.abc.xyz
10      f.abc.xyz
11      g.abc.xyz
12      h.abc.xyz
13      i.abc.xyz
14      j.abc.xyz
18      k.abc.xyz
19      l.abc.xyz
20      m.abc.xyz
22      n.abc.xyz
23      o.abc.xyz
30      p.abc.xyz
31      q.abc.xyz
32      r.abc.xyz
33      s.abc.xyz
34      t.abc.xyz
35      u.abc.xyz
36      v.abc.xyz
37      w.abc.xyz
38      x.abc.xyz
39      y.abc.xyz
49      z.abc.xyz\n\n${NOCOLOR}"

# Ask the user for the cert number
echo certificat number ?
read varname
echo -e "${BLUE} FULLCHAIN:\n\n"
cat "$(ls -rt /etc/letsencrypt/archive/npm-$varname/fullchain* | tail -n1)"
echo -e "${NOCOLOR}\n\n "
echo -e "\n ${GREEN} PRIVATE:\n\n"
cat "$(ls -rt /etc/letsencrypt/archive/npm-$varname/privkey* | tail -n1)"
echo -e "${NOCOLOR}\n\n "

certificates numbers found in /data/database.sqlite

hope this can be useful

<!-- gh-comment-id:1051974302 --> @captainabloc commented on GitHub (Feb 26, 2022): Hi all, here a small script for retrieving latest Fullchain and Privatekey from NPM. Usefull for example for Adguardhome certificates renewal: ``` #!/bin/bash # ---------------------------------- # Colors # ---------------------------------- NOCOLOR='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' ORANGE='\033[0;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' LIGHTGRAY='\033[0;37m' DARKGRAY='\033[1;30m' LIGHTRED='\033[1;31m' LIGHTGREEN='\033[1;32m' YELLOW='\033[1;33m' LIGHTBLUE='\033[1;34m' LIGHTPURPLE='\033[1;35m' LIGHTCYAN='\033[1;36m' WHITE='\033[1;37m' echo -e "${YELLOW}\n 1 abc.xyz 5 a.abc.xyz 6 b.abc.xyz 7 c.abc.xyz 8 d.abc.xyz 9 e.abc.xyz 10 f.abc.xyz 11 g.abc.xyz 12 h.abc.xyz 13 i.abc.xyz 14 j.abc.xyz 18 k.abc.xyz 19 l.abc.xyz 20 m.abc.xyz 22 n.abc.xyz 23 o.abc.xyz 30 p.abc.xyz 31 q.abc.xyz 32 r.abc.xyz 33 s.abc.xyz 34 t.abc.xyz 35 u.abc.xyz 36 v.abc.xyz 37 w.abc.xyz 38 x.abc.xyz 39 y.abc.xyz 49 z.abc.xyz\n\n${NOCOLOR}" # Ask the user for the cert number echo certificat number ? read varname echo -e "${BLUE} FULLCHAIN:\n\n" cat "$(ls -rt /etc/letsencrypt/archive/npm-$varname/fullchain* | tail -n1)" echo -e "${NOCOLOR}\n\n " echo -e "\n ${GREEN} PRIVATE:\n\n" cat "$(ls -rt /etc/letsencrypt/archive/npm-$varname/privkey* | tail -n1)" echo -e "${NOCOLOR}\n\n " ``` certificates numbers found in `/data/database.sqlite` hope this can be useful
Author
Owner

@balya commented on GitHub (Jan 11, 2023):

I use NPM on my Unaraid server.
Wrote a small script to transfer keys to another server with OPNsense. Perhaps someone will come in handy.
I run the script according to the schedule through the plugin User Scripts.

#!/usr/bin/python3
import os
from pathlib import Path
from paramiko import SSHClient
from scp import SCPClient
from paramiko import AutoAddPolicy, RSAKey, SSHClient

proxy_hosts_dir = '/mnt/user/appdata/Nginx-Proxy-Manager-Official/data/nginx/proxy_host'
archive_dir = '/mnt/user/appdata/Nginx-Proxy-Manager-Official/letsencrypt/archive'
target_host = 'dns.host'
host_file = ''

for filename in os.listdir(proxy_hosts_dir):
    file = os.path.join(proxy_hosts_dir, filename)
    if os.path.isfile(file) and filename.endswith('.conf'):
        with open(file) as f:
            if target_host in f.read():
                host_file = file

archive_id = int(Path(host_file).stem) + 1
archive_path = archive_dir + '/npm-' + str(archive_id)

max_cert = int(1)
for certfilename in os.listdir(archive_path):
    certfile = os.path.join(archive_path, certfilename)
    index = int(''.join(filter(lambda i: i.isdigit(), certfilename)))
    if index > max_cert:
        max_cert = index

fullchain = archive_path + '/fullchain' + str(max_cert) + '.pem'
privkey = archive_path + '/privkey' + str(max_cert) + '.pem'

client = SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(AutoAddPolicy())
client.connect('192.168.1.1', username='unraid')
sftp = client.open_sftp()
sftp.put(fullchain, '/home/unraid/letsencrypt/' + target_host + '.fullchain.pem')
sftp.put(privkey, '/home/unraid/letsencrypt/' + target_host + '.privkey.pem')
sftp.close()
<!-- gh-comment-id:1379361331 --> @balya commented on GitHub (Jan 11, 2023): I use NPM on my Unaraid server. Wrote a small script to transfer keys to another server with OPNsense. Perhaps someone will come in handy. I run the script according to the schedule through the plugin `User Scripts`. ```python #!/usr/bin/python3 import os from pathlib import Path from paramiko import SSHClient from scp import SCPClient from paramiko import AutoAddPolicy, RSAKey, SSHClient proxy_hosts_dir = '/mnt/user/appdata/Nginx-Proxy-Manager-Official/data/nginx/proxy_host' archive_dir = '/mnt/user/appdata/Nginx-Proxy-Manager-Official/letsencrypt/archive' target_host = 'dns.host' host_file = '' for filename in os.listdir(proxy_hosts_dir): file = os.path.join(proxy_hosts_dir, filename) if os.path.isfile(file) and filename.endswith('.conf'): with open(file) as f: if target_host in f.read(): host_file = file archive_id = int(Path(host_file).stem) + 1 archive_path = archive_dir + '/npm-' + str(archive_id) max_cert = int(1) for certfilename in os.listdir(archive_path): certfile = os.path.join(archive_path, certfilename) index = int(''.join(filter(lambda i: i.isdigit(), certfilename))) if index > max_cert: max_cert = index fullchain = archive_path + '/fullchain' + str(max_cert) + '.pem' privkey = archive_path + '/privkey' + str(max_cert) + '.pem' client = SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(AutoAddPolicy()) client.connect('192.168.1.1', username='unraid') sftp = client.open_sftp() sftp.put(fullchain, '/home/unraid/letsencrypt/' + target_host + '.fullchain.pem') sftp.put(privkey, '/home/unraid/letsencrypt/' + target_host + '.privkey.pem') sftp.close() ```
Author
Owner

@Moonbase59 commented on GitHub (Mar 29, 2023):

@Balya Thanks for your suggestion!

I run Prosody as a chat server (not on the NGINX Proxy Manager machine) and also need to transfer the certs to Prosody. I found the numbering scheme you use above not reliable, especially when making NPM configuration changes. So I opted for actually reading the relevant parts of NPM’s .conf files. (Excuse my bad Python…)

#!/usr/bin/python3
import re
import os
from pathlib import Path
from paramiko import SSHClient
from scp import SCPClient
from paramiko import AutoAddPolicy, RSAKey, SSHClient

proxy_hosts_dir = '/home/admin/npm/data/nginx/proxy_host'
archive_dir = '/home/admin/npm/letsencrypt/live'
target_host = 'chat.mydomain.net'
host_file = ''

for filename in os.listdir(proxy_hosts_dir):
    file = os.path.join(proxy_hosts_dir, filename)
    if os.path.isfile(file) and filename.endswith('.conf'):
        with open(file) as f:
            content = f.read();
            m = re.search(r'server_name\s+(.*);', content)
            if m:
              s = m.group(1).split()
              basename = ('_').join(s).replace("*", "x")
              if target_host in s:
                f = re.search(r'ssl_certificate\s+/etc/letsencrypt/live(.*);', content)
                if f:
                  fullchain = archive_dir + f.group(1)
                p = re.search(r'ssl_certificate_key\s+/etc/letsencrypt/live(.*);', content)
                if p:
                  privkey = archive_dir + p.group(1)

client = SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(AutoAddPolicy())
client.connect('prosody', username='myusername')
sftp = client.open_sftp()
sftp.put(fullchain, '/home/myusername/certs/' + target_host + '.fullchain.pem')
sftp.put(privkey, '/home/myusername/certs/' + target_host + '.privkey.pem')
sftp.close()

This script I run via root’s crontab on the NPM machine every night at 3:00 a.m. like so:

0 3 * * * /home/admin/bin/ssl-chat.py

And on the Prosody machine, since it can’t reload correctly, at 3:10 a.m., also via root’s crontab:

10 3 * * * prosodyctl --root cert import chat.mydomain.net /home/myusername/certs/

Works well so far. Maybe this can help others, too.

<!-- gh-comment-id:1489135009 --> @Moonbase59 commented on GitHub (Mar 29, 2023): @Balya Thanks for your suggestion! I run Prosody as a chat server (not on the NGINX Proxy Manager machine) and also need to transfer the certs to Prosody. I found the numbering scheme you use above not reliable, especially when making NPM configuration changes. So I opted for actually reading the relevant parts of NPM’s `.conf` files. (Excuse my bad Python…) ```python #!/usr/bin/python3 import re import os from pathlib import Path from paramiko import SSHClient from scp import SCPClient from paramiko import AutoAddPolicy, RSAKey, SSHClient proxy_hosts_dir = '/home/admin/npm/data/nginx/proxy_host' archive_dir = '/home/admin/npm/letsencrypt/live' target_host = 'chat.mydomain.net' host_file = '' for filename in os.listdir(proxy_hosts_dir): file = os.path.join(proxy_hosts_dir, filename) if os.path.isfile(file) and filename.endswith('.conf'): with open(file) as f: content = f.read(); m = re.search(r'server_name\s+(.*);', content) if m: s = m.group(1).split() basename = ('_').join(s).replace("*", "x") if target_host in s: f = re.search(r'ssl_certificate\s+/etc/letsencrypt/live(.*);', content) if f: fullchain = archive_dir + f.group(1) p = re.search(r'ssl_certificate_key\s+/etc/letsencrypt/live(.*);', content) if p: privkey = archive_dir + p.group(1) client = SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(AutoAddPolicy()) client.connect('prosody', username='myusername') sftp = client.open_sftp() sftp.put(fullchain, '/home/myusername/certs/' + target_host + '.fullchain.pem') sftp.put(privkey, '/home/myusername/certs/' + target_host + '.privkey.pem') sftp.close() ``` This script I run via root’s crontab on the NPM machine every night at 3:00 a.m. like so: ```cron 0 3 * * * /home/admin/bin/ssl-chat.py ``` And on the Prosody machine, since it can’t reload correctly, at 3:10 a.m., also via root’s crontab: ```cron 10 3 * * * prosodyctl --root cert import chat.mydomain.net /home/myusername/certs/ ``` Works well so far. Maybe this can help others, too.
Author
Owner

@smooth-baking-powder commented on GitHub (May 20, 2023):

@Balya Thanks for your suggestion!

I run Prosody as a chat server (not on the NGINX Proxy Manager machine) and also need to transfer the certs to Prosody. I found the numbering scheme you use above not reliable, especially when making NPM configuration changes. So I opted for actually reading the relevant parts of NPM’s .conf files. (Excuse my bad Python…)

#!/usr/bin/python3
import re
import os
from pathlib import Path
from paramiko import SSHClient
from scp import SCPClient
from paramiko import AutoAddPolicy, RSAKey, SSHClient

proxy_hosts_dir = '/home/admin/npm/data/nginx/proxy_host'
archive_dir = '/home/admin/npm/letsencrypt/live'
target_host = 'chat.mydomain.net'
host_file = ''

for filename in os.listdir(proxy_hosts_dir):
    file = os.path.join(proxy_hosts_dir, filename)
    if os.path.isfile(file) and filename.endswith('.conf'):
        with open(file) as f:
            content = f.read();
            m = re.search(r'server_name\s+(.*);', content)
            if m:
              s = m.group(1).split()
              basename = ('_').join(s).replace("*", "x")
              if target_host in s:
                f = re.search(r'ssl_certificate\s+/etc/letsencrypt/live(.*);', content)
                if f:
                  fullchain = archive_dir + f.group(1)
                p = re.search(r'ssl_certificate_key\s+/etc/letsencrypt/live(.*);', content)
                if p:
                  privkey = archive_dir + p.group(1)

client = SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(AutoAddPolicy())
client.connect('prosody', username='myusername')
sftp = client.open_sftp()
sftp.put(fullchain, '/home/myusername/certs/' + target_host + '.fullchain.pem')
sftp.put(privkey, '/home/myusername/certs/' + target_host + '.privkey.pem')
sftp.close()

This script I run via root’s crontab on the NPM machine every night at 3:00 a.m. like so:

0 3 * * * /home/admin/bin/ssl-chat.py

And on the Prosody machine, since it can’t reload correctly, at 3:10 a.m., also via root’s crontab:

10 3 * * * prosodyctl --root cert import chat.mydomain.net /home/myusername/certs/

Works well so far. Maybe this can help others, too.

If i use your script and edit the paths and username etc. i get this Error:
Traceback (most recent call last):
File "/root/./turn-ssl.sh", line 36, in
sftp.put(fullchain, '/opt/coturn/cert/' + target_host + '.fullchain.pem')
NameError: name 'fullchain' is not defined

No idea, how i can solve it

<!-- gh-comment-id:1556023666 --> @smooth-baking-powder commented on GitHub (May 20, 2023): > @Balya Thanks for your suggestion! > > I run Prosody as a chat server (not on the NGINX Proxy Manager machine) and also need to transfer the certs to Prosody. I found the numbering scheme you use above not reliable, especially when making NPM configuration changes. So I opted for actually reading the relevant parts of NPM’s `.conf` files. (Excuse my bad Python…) > > ```python > #!/usr/bin/python3 > import re > import os > from pathlib import Path > from paramiko import SSHClient > from scp import SCPClient > from paramiko import AutoAddPolicy, RSAKey, SSHClient > > proxy_hosts_dir = '/home/admin/npm/data/nginx/proxy_host' > archive_dir = '/home/admin/npm/letsencrypt/live' > target_host = 'chat.mydomain.net' > host_file = '' > > for filename in os.listdir(proxy_hosts_dir): > file = os.path.join(proxy_hosts_dir, filename) > if os.path.isfile(file) and filename.endswith('.conf'): > with open(file) as f: > content = f.read(); > m = re.search(r'server_name\s+(.*);', content) > if m: > s = m.group(1).split() > basename = ('_').join(s).replace("*", "x") > if target_host in s: > f = re.search(r'ssl_certificate\s+/etc/letsencrypt/live(.*);', content) > if f: > fullchain = archive_dir + f.group(1) > p = re.search(r'ssl_certificate_key\s+/etc/letsencrypt/live(.*);', content) > if p: > privkey = archive_dir + p.group(1) > > client = SSHClient() > client.load_system_host_keys() > client.set_missing_host_key_policy(AutoAddPolicy()) > client.connect('prosody', username='myusername') > sftp = client.open_sftp() > sftp.put(fullchain, '/home/myusername/certs/' + target_host + '.fullchain.pem') > sftp.put(privkey, '/home/myusername/certs/' + target_host + '.privkey.pem') > sftp.close() > ``` > > This script I run via root’s crontab on the NPM machine every night at 3:00 a.m. like so: > > ``` > 0 3 * * * /home/admin/bin/ssl-chat.py > ``` > > And on the Prosody machine, since it can’t reload correctly, at 3:10 a.m., also via root’s crontab: > > ``` > 10 3 * * * prosodyctl --root cert import chat.mydomain.net /home/myusername/certs/ > ``` > > Works well so far. Maybe this can help others, too. If i use your script and edit the paths and username etc. i get this Error: Traceback (most recent call last): File "/root/./turn-ssl.sh", line 36, in <module> sftp.put(fullchain, '/opt/coturn/cert/' + target_host + '.fullchain.pem') NameError: name 'fullchain' is not defined No idea, how i can solve it
Author
Owner

@LazyGatto commented on GitHub (Aug 16, 2023):

I tried to write a sample script to export certificates from Nginx Proxy Manager for use with mailcow mail server. You can adapt it to use with any application. https://github.com/LazyGatto/npm-cert-export

<!-- gh-comment-id:1680409485 --> @LazyGatto commented on GitHub (Aug 16, 2023): I tried to write a sample script to export certificates from Nginx Proxy Manager for use with mailcow mail server. You can adapt it to use with any application. https://github.com/LazyGatto/npm-cert-export
Author
Owner

@psychogun commented on GitHub (Aug 20, 2023):

This is my take on it; one VM with NPM container (192.168.0.44)- another VM with a ZNC bouncer from where the bash script is run in a cron job from the root user, every 90 days. First execution is on the 25th of September 2023.

If you go to SSL Certificates in NPM, you can see which #number the certificate it is listed as (/home/yoyo/podman/npm/letsencrypt/live/npm-13) when you download it manually.

Cron:
crontab -e 0 0 25 9 */90 /root/fullchain_download.sh

I am running the ZNC bouncer as a regular user (wwhite) as a systems service (systemctl --user start container-znc.service) and I had some issues writing the files in to the shared directory with podman from that user. Therefore I opted to copy the root user's public key in to .ssh/authorized_keys on the yoyo user running NPM on the other machine.

#!/bin/bash


# Server details
SERVER_IP="192.168.0.44"
SSH_USER="yoyo"
REMOTE_DIR="/home/yoyo/podman/npm/letsencrypt/live/npm-13"

# Local directory
LOCAL_TMP="/home/wwhite/tmp"
LOCAL_ZNC="/home/wwhite/podman/znc"

# List of file names to download
FULLCHAIN="fullchain.pem"
PRIVKEY="privkey.pem"
FILES=("$FULLCHAIN" "$PRIVKEY")

echo "Attempting to connect to $SERVER_IP"

for FILE in "${FILES[@]}"; do
    scp "$SSH_USER@$SERVER_IP:$REMOTE_DIR/$FILE" "$LOCAL_TMP/"
    echo "$FILE downloaded to $LOCAL_TMP"
done

echo "Combining keys"
cat "$LOCAL_TMP/$PRIVKEY" > "$LOCAL_TMP/znc.pem"
cat "$LOCAL_TMP/$FULLCHAIN" >> "$LOCAL_TMP/znc.pem"

echo "Privkey and fullchain is combined to znc.pem"

mv "$LOCAL_TMP/znc.pem" "$LOCAL_ZNC"

echo "The combined znc.pem is moved in to the appropriate directory"

# Clean up process

rm $LOCAL_TMP/$FULLCHAIN
echo "Removed the temporary $FULLCHAIN"


rm $LOCAL_TMP/$PRIVKEY
echo "Removed the temporary $PRIVKEY"

chmod 0600 $LOCAL_ZNC/znc.pem
echo "Permission 0600 znc.pem"

<!-- gh-comment-id:1685139653 --> @psychogun commented on GitHub (Aug 20, 2023): This is my take on it; one VM with NPM container (192.168.0.44)- another VM with a ZNC bouncer from where the bash script is run in a cron job from the root user, every 90 days. First execution is on the 25th of September 2023. If you go to SSL Certificates in NPM, you can see which #number the certificate it is listed as (`/home/yoyo/podman/npm/letsencrypt/live/npm-13`) when you download it manually. Cron: `crontab -e 0 0 25 9 */90 /root/fullchain_download.sh` I am running the ZNC bouncer as a regular user (`wwhite`) as a systems service (`systemctl --user start container-znc.service`) and I had some issues writing the files in to the shared directory with podman from that user. Therefore I opted to copy the `root` user's public key in to `.ssh/authorized_keys` on the `yoyo` user running NPM on the other machine. ``` #!/bin/bash # Server details SERVER_IP="192.168.0.44" SSH_USER="yoyo" REMOTE_DIR="/home/yoyo/podman/npm/letsencrypt/live/npm-13" # Local directory LOCAL_TMP="/home/wwhite/tmp" LOCAL_ZNC="/home/wwhite/podman/znc" # List of file names to download FULLCHAIN="fullchain.pem" PRIVKEY="privkey.pem" FILES=("$FULLCHAIN" "$PRIVKEY") echo "Attempting to connect to $SERVER_IP" for FILE in "${FILES[@]}"; do scp "$SSH_USER@$SERVER_IP:$REMOTE_DIR/$FILE" "$LOCAL_TMP/" echo "$FILE downloaded to $LOCAL_TMP" done echo "Combining keys" cat "$LOCAL_TMP/$PRIVKEY" > "$LOCAL_TMP/znc.pem" cat "$LOCAL_TMP/$FULLCHAIN" >> "$LOCAL_TMP/znc.pem" echo "Privkey and fullchain is combined to znc.pem" mv "$LOCAL_TMP/znc.pem" "$LOCAL_ZNC" echo "The combined znc.pem is moved in to the appropriate directory" # Clean up process rm $LOCAL_TMP/$FULLCHAIN echo "Removed the temporary $FULLCHAIN" rm $LOCAL_TMP/$PRIVKEY echo "Removed the temporary $PRIVKEY" chmod 0600 $LOCAL_ZNC/znc.pem echo "Permission 0600 znc.pem" ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/nginx-proxy-manager-NginxProxyManager#578
No description provided.