├── ansible ├── roles │ └── zen-node │ │ ├── defaults │ │ └── main.yml │ │ ├── handlers │ │ └── main.yml │ │ ├── templates │ │ ├── zenupdate.timer │ │ ├── zenupdate.service │ │ ├── zen.conf.j2 │ │ ├── zen-node.service │ │ ├── config.json.j2 │ │ └── zen-secnodetracker.service │ │ └── tasks │ │ └── main.yml ├── output.j2 ├── hosts ├── bootstrap.yml ├── upgrade.yml ├── main.yml ├── status.yml └── README.md ├── secnodetracker ├── zen-secnodetracker.service ├── entrypoint.sh └── Dockerfile ├── zend ├── zen-node.service ├── Dockerfile └── entrypoint.sh ├── README.md └── install.sh /ansible/roles/zen-node/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | zen_node_port: 9033 3 | -------------------------------------------------------------------------------- /ansible/roles/zen-node/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart_zen-secnodetracker 4 | service: name=zen-secnodetracker state=restarted enabled=yes 5 | 6 | - name: restart_zen-node 7 | service: name=zen-node state=restarted enabled=yes 8 | -------------------------------------------------------------------------------- /ansible/output.j2: -------------------------------------------------------------------------------- 1 | {% for host in groups['zen-nodes'] %} 2 | 3 | {{ host }}: 4 | 5 | Shield Address: {{ hostvars[host]['zenshield']}} 6 | 7 | Current {{ hostvars[host]['zenblock']}} 8 | 9 | Balance: {{ hostvars[host]['zenbalance']}} 10 | 11 | {%endfor%} 12 | -------------------------------------------------------------------------------- /ansible/hosts: -------------------------------------------------------------------------------- 1 | # Parameters passed to all hosts 2 | [all:vars] 3 | email=test@example.com 4 | cert_email=test@example.com 5 | region=sea 6 | 7 | [zen-nodes] 8 | localhost fqdn=node.example.com stakeaddr=test nodetype=secure cert_domain=nodename.example.com 9 | 10 | [bootstrap-nodes] 11 | -------------------------------------------------------------------------------- /ansible/roles/zen-node/templates/zenupdate.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Run zenupdate unit daily @ 06:00:00 (UTC) 3 | Requires=zenupdate.service 4 | [Timer] 5 | OnCalendar=*-*-* 06:00:00 6 | Unit=zenupdate.service 7 | Persistent=true 8 | [Install] 9 | WantedBy=multi-user.target 10 | WantedBy=timers.target 11 | -------------------------------------------------------------------------------- /ansible/roles/zen-node/templates/zenupdate.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Zen Certbot certificate updater 3 | [Service] 4 | Type=oneshot 5 | ExecStart=/usr/bin/certbot -q renew --deploy-hook 'systemctl restart zen-node && systemctl restart zen-secnodetracker && docker rmi $(docker images --quiet --filter "dangling=true")' 6 | PrivateTmp=true" | tee /lib/systemd/system/zenupdate.service 7 | -------------------------------------------------------------------------------- /ansible/roles/zen-node/templates/zen.conf.j2: -------------------------------------------------------------------------------- 1 | rpcport=18231 2 | rpcallowip=127.0.0.1 3 | rpcworkqueue=512 4 | server=1 5 | # Docker doesn't run as daemon 6 | daemon=0 7 | listen=1 8 | txindex=1 9 | logtimestamps=1 10 | testnet=0 11 | rpcuser=user 12 | rpcpassword={{ rpcpassword.stdout }} 13 | tlscertpath=/etc/letsencrypt/live/{{ fqdn }}/cert.pem 14 | tlskeypath=/etc/letsencrypt/live/{{ fqdn }}/privkey.pem 15 | 16 | # add external IPs 17 | {% for externalIP in externalIP_list %} 18 | externalip={{ externalIP }} 19 | {% endfor %} 20 | port={{ zen_node_port }} 21 | -------------------------------------------------------------------------------- /ansible/bootstrap.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Bootstrap new zen secure nodes 3 | 4 | - name: Bootstrap new zen secure nodes 5 | hosts: bootstrap-nodes 6 | gather_facts: false 7 | remote_user: root 8 | 9 | tasks: 10 | - name: install python 2 11 | raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal) 12 | 13 | - name: Bootstraping blockchain to new nodes (this may take a while) 14 | copy: 15 | src: "/mnt/zen/config/{{ item }}" 16 | dest: "/mnt/zen/config/" 17 | with_items: 18 | - 'blocks' 19 | - 'chainstate' 20 | - 'database' 21 | -------------------------------------------------------------------------------- /ansible/roles/zen-node/templates/zen-node.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Zen Daemon Container 3 | After=docker.service 4 | Requires=docker.service 5 | [Service] 6 | TimeoutStartSec=10m 7 | Restart=always 8 | ExecStartPre=-/usr/bin/docker stop zen-node 9 | ExecStartPre=-/usr/bin/docker rm zen-node 10 | # Always pull the latest docker image 11 | ExecStartPre=/usr/bin/docker pull whenlambomoon/zend:latest 12 | ExecStart=/usr/bin/docker run --rm --net=host -p 9033:9033 -p 18231:18231 -v /mnt/zen:/mnt/zen -v /etc/letsencrypt/:/etc/letsencrypt/ --name zen-node whenlambomoon/zend:latest 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /secnodetracker/zen-secnodetracker.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Zen secnodetracker Container 3 | After=docker.service 4 | Requires=docker.service 5 | 6 | [Service] 7 | TimeoutStartSec=10m 8 | Restart=always 9 | ExecStartPre=-/usr/bin/docker stop %i 10 | ExecStartPre=-/usr/bin/docker rm %i 11 | # Always pull the latest docker image 12 | ExecStartPre=/usr/bin/docker pull whenlambomoon/secnodetracker:latest 13 | ExecStart=/usr/bin/docker run --rm \ 14 | -v /mnt/zen:/mnt/zen \ 15 | --name secnode whenlambomoon/secnodetracker 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /ansible/roles/zen-node/templates/config.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "active": "{{ nodetype }}", 3 | "{{ nodetype }}": { 4 | "nodetype": "{{ nodetype }}", 5 | "nodeid": null, 6 | "servers": [ 7 | "{{ servers }}2.eu", 8 | "{{ servers }}1.eu", 9 | "{{ servers }}3.eu", 10 | "{{ servers }}4.eu", 11 | "{{ servers }}4.na", 12 | "{{ servers }}3.na", 13 | "{{ servers }}2.na", 14 | "{{ servers }}1.na" 15 | ], 16 | "stakeaddr": "{{ stakeaddr }}", 17 | "email": "{{ email }}", 18 | "fqdn": "{{ fqdn }}", 19 | "ipv": "4", 20 | "region": "{{ region }}", 21 | "home": "ts1.{{ region }}", 22 | "category": "none" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /zend/zen-node.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Zen Daemon Container 3 | After=docker.service 4 | Requires=docker.service 5 | 6 | [Service] 7 | TimeoutStartSec=10m 8 | Restart=always 9 | ExecStartPre=-/usr/bin/docker stop %i 10 | ExecStartPre=-/usr/bin/docker rm %i 11 | # Always pull the latest docker image 12 | ExecStartPre=/usr/bin/docker pull whenlambomoon/zend:latest 13 | ExecStart=/usr/bin/docker run --rm \ 14 | -p 9033:9033 \ 15 | -p 18231:18231 \ 16 | -v /mnt/zen:/mnt/zen \ 17 | --name zend zend 18 | [Install] 19 | WantedBy=multi-user.target 20 | -------------------------------------------------------------------------------- /secnodetracker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # link the secure node tracker config, bail if not present 4 | if [ -f "/mnt/zen/secnode/config.json" ]; then 5 | echo "Secure node config found OK - linking..." 6 | ln -s /mnt/zen/secnode /home/node/secnodetracker/config > /dev/null 2>&1 || true 7 | else 8 | echo "No secure node config found. exiting" 9 | exit 1 10 | fi 11 | 12 | # Copy the zencash params 13 | cp -r /mnt/zen/zcash-params /mnt/zcash-params 14 | 15 | # Fix the permissons 16 | chown -R node:node /mnt/zen/secnode /mnt/zcash-params /home/node/secnodetracker 17 | chmod g+rw /mnt/zen/secnode /home/node/secnodetracker 18 | chmod -R 777 /home/node/secnodetracker/config 19 | 20 | cd /home/node/secnodetracker 21 | gosu node node app.js 22 | -------------------------------------------------------------------------------- /ansible/roles/zen-node/templates/zen-secnodetracker.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Zen Secnodetracker Container 3 | After=docker.service 4 | Requires=docker.service 5 | [Service] 6 | TimeoutStartSec=10m 7 | Restart=always 8 | ExecStartPre=-/usr/bin/docker stop zen-secnodetracker 9 | ExecStartPre=-/usr/bin/docker rm zen-secnodetracker 10 | # Always pull the latest docker image 11 | ExecStartPre=/usr/bin/docker pull whenlambomoon/secnodetracker:latest 12 | #ExecStart=/usr/bin/docker run --init --rm --net=host -v /mnt/zen:/mnt/zen --name zen-secnodetracker whenlambomoon/secnodetracker:latest 13 | ExecStart=/usr/bin/docker run --rm --net=host -v /mnt/zen:/mnt/zen --name zen-secnodetracker whenlambomoon/secnodetracker:latest 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /ansible/upgrade.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Upgrade zen secure nodes 3 | 4 | - name: upgrade zen secnodes 5 | hosts: zen-nodes 6 | gather_facts: false 7 | remote_user: root 8 | 9 | tasks: 10 | - name: install python 2 11 | raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal) 12 | 13 | - name: Upgrading zen-node 14 | service: 15 | name: zen-node 16 | state: restarted 17 | enabled: yes 18 | 19 | - name: Upgrading zen-secnodetracker 20 | service: 21 | name: zen-secnodetracker 22 | state: restarted 23 | enabled: yes 24 | 25 | - name: Removing old/unused docker images 26 | shell: | 27 | docker rmi $(docker images --filter "dangling=true" -q --no-trunc) 28 | ignore_errors: yes 29 | -------------------------------------------------------------------------------- /ansible/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Deploy zen-node and zen-securenodetracker 3 | 4 | - name: configure and deploy zen secnodes 5 | hosts: zen-nodes 6 | remote_user: root 7 | gather_facts: false 8 | pre_tasks: 9 | - name: Install python2 for Ansible 10 | raw: bash -c "test -e /usr/bin/python || (apt -qqy update && apt install -qqy python-minimal)" 11 | register: output 12 | changed_when: output.stdout != "" 13 | - name: Gathering Facts 14 | setup: 15 | roles: 16 | - zen-node 17 | 18 | - hosts: localhost 19 | connection: local 20 | gather_facts: false 21 | tasks: 22 | - name: copy results to local file 23 | template: src=output.j2 dest="/tmp/zen-node-results" 24 | 25 | - name: output results 26 | command: cat /tmp/zen-node-results 27 | register: cat 28 | - debug: var=cat.stdout_lines 29 | -------------------------------------------------------------------------------- /ansible/status.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Check the status of all zen-nodes 3 | 4 | - name: Check the status of all zen-nodes 5 | hosts: zen-nodes 6 | remote_user: root 7 | tasks: 8 | - name: Get current block 9 | shell: | 10 | docker exec zen-node /usr/local/bin/gosu user zen-cli getinfo | grep \"blocks\" | tr -d \", 11 | register: zenblock 12 | 13 | - name: Get shield address 14 | shell: | 15 | docker exec zen-node /usr/local/bin/gosu user zen-cli z_listaddresses | tr -d []\"' ' 16 | register: zenshield 17 | 18 | - name: Get shield address balance 19 | shell: | 20 | docker exec zen-node /usr/local/bin/gosu user zen-cli z_gettotalbalance | tr -d {}\", 21 | register: zenbalance 22 | 23 | - set_fact: 24 | zenblock: "{{ zenblock.stdout }}" 25 | zenshield: "{{ zenshield.stdout }}" 26 | zenbalance: "{{ zenbalance.stdout }}" 27 | 28 | - hosts: localhost 29 | connection: local 30 | gather_facts: false 31 | tasks: 32 | - name: copy results to local file 33 | template: src=output.j2 dest="/tmp/zen-node-results" 34 | 35 | - name: output results 36 | command: cat /tmp/zen-node-results 37 | register: cat 38 | - debug: var=cat.stdout_lines 39 | -------------------------------------------------------------------------------- /secnodetracker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8 2 | 3 | ENV TINI_VERSION v0.16.1 4 | ENV NODE_ENV production 5 | ENV ZENCONF /mnt/zen/config/zen.conf 6 | ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini 7 | RUN chmod +x /tini 8 | 9 | RUN latestBaseurl="$(curl -s https://api.github.com/repos/tianon/gosu/releases | grep browser_download_url | head -n 1 | cut -d '"' -f 4 | sed 's:/[^/]*$::')" \ 10 | && dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \ 11 | && curl -o /usr/local/bin/gosu -SL "$latestBaseurl/gosu-$dpkgArch" \ 12 | && curl -o /usr/local/bin/gosu.asc -SL "$latestBaseurl/gosu-$dpkgArch.asc" \ 13 | && export GNUPGHOME="$(mktemp -d)" \ 14 | && echo "disable-ipv6" >> $GNUPGHOME/dirmngr.conf \ 15 | && gpg --no-tty --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ 16 | && gpg --no-tty --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ 17 | && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ 18 | && chmod +x /usr/local/bin/gosu \ 19 | && gosu nobody true \ 20 | 21 | WORKDIR /home/node/ 22 | 23 | RUN cd /home/node/ \ 24 | && git clone https://github.com/ZencashOfficial/secnodetracker.git \ 25 | && cd secnodetracker \ 26 | && npm install 27 | 28 | COPY entrypoint.sh /usr/local/bin/entrypoint.sh 29 | 30 | ENTRYPOINT ["/tini", "--", "/usr/local/bin/entrypoint.sh"] 31 | -------------------------------------------------------------------------------- /zend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | # Used only for triggering a rebuild 4 | LABEL zend="2.0.19" 5 | 6 | RUN apt-get update \ 7 | && DEBIAN_FRONTEND=noninteractive apt-get -y --no-install-recommends install ca-certificates curl wget apt-transport-https lsb-release libgomp1 jq \ 8 | && echo 'deb https://zencashofficial.github.io/repo/ '$(lsb_release -cs)' main' | tee --append /etc/apt/sources.list.d/zen.list \ 9 | && gpg --keyserver ha.pool.sks-keyservers.net --recv 219F55740BBF7A1CE368BA45FB7053CE4991B669 \ 10 | && gpg --export 219F55740BBF7A1CE368BA45FB7053CE4991B669 | apt-key add - \ 11 | && apt-get update \ 12 | && DEBIAN_FRONTEND=noninteractive apt-get install zen \ 13 | && latestBaseurl="$(curl -s https://api.github.com/repos/tianon/gosu/releases | grep browser_download_url | head -n 1 | cut -d '"' -f 4 | sed 's:/[^/]*$::')" \ 14 | && dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \ 15 | && curl -o /usr/local/bin/gosu -SL "$latestBaseurl/gosu-$dpkgArch" \ 16 | && curl -o /usr/local/bin/gosu.asc -SL "$latestBaseurl/gosu-$dpkgArch.asc" \ 17 | && export GNUPGHOME="$(mktemp -d)" \ 18 | && gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ 19 | && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ 20 | && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \ 21 | && chmod +x /usr/local/bin/gosu \ 22 | && gosu nobody true \ 23 | && apt-get clean \ 24 | && rm -rf /var/lib/apt/lists/* 25 | 26 | # Default p2p communication port, can be changed via $OPTS (e.g. docker run -e OPTS="-port=9876") 27 | # or via a "port=9876" line in zen.conf. 28 | #Defaults are 9033/19033 (Testnet) 29 | EXPOSE 9033 30 | EXPOSE 19033 31 | 32 | # Default rpc communication port, can be changed via $OPTS (e.g. docker run -e OPTS="-rpcport=8765") 33 | # or via a "rpcport=8765" line in zen.conf. This port should never be mapped to the outside world 34 | # via the "docker run -p/-P" command. 35 | #Defaults are 8231/18231 (Testnet) 36 | EXPOSE 8231 37 | EXPOSE 18231 38 | 39 | # Data volumes, if you prefer mounting a host directory use "-v /path:/mnt/zen" command line 40 | # option (folder ownership will be changed to the same UID/GID as provided by the docker run command) 41 | VOLUME ["/mnt/zen"] 42 | 43 | COPY entrypoint.sh /usr/local/bin/entrypoint.sh 44 | ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] 45 | 46 | CMD ["zend"] 47 | -------------------------------------------------------------------------------- /zend/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Add local user 5 | # Either use the LOCAL_USER_ID if passed in at runtime or 6 | # fallback 7 | USER_ID=${LOCAL_USER_ID:-9001} 8 | GRP_ID=${LOCAL_GRP_ID:-9001} 9 | 10 | getent group user > /dev/null 2>&1 || groupadd -g $GRP_ID user 11 | id -u user > /dev/null 2>&1 || useradd --shell /bin/bash -u $USER_ID -g $GRP_ID -o -c "" -m user 12 | 13 | LOCAL_UID=$(id -u user) 14 | LOCAL_GID=$(getent group user | cut -d ":" -f 3) 15 | 16 | if [ ! "$USER_ID" == "$LOCAL_UID" ] || [ ! "$GRP_ID" == "$LOCAL_GID" ]; then 17 | echo "Warning: User with differing UID "$LOCAL_UID"/GID "$LOCAL_GID" already exists, most likely this container was started before with a different UID/GID. Re-create it to change UID/GID." 18 | fi 19 | 20 | echo "Starting with UID/GID : "$(id -u user)"/"$(getent group user | cut -d ":" -f 3) 21 | 22 | export HOME=/home/user 23 | 24 | # Must have a zen config file 25 | if [ ! -f "/mnt/zen/config/zen.conf" ]; then 26 | echo "No config found. Exiting." 27 | exit 1 28 | else 29 | if [ ! -L $HOME/.zen ]; then 30 | ln -s /mnt/zen/config $HOME/.zen > /dev/null 2>&1 || true 31 | fi 32 | fi 33 | 34 | # zcash-params can be symlinked in from an external volume or created locally 35 | if [ -d "/mnt/zen/zcash-params" ]; then 36 | if [ ! -L $HOME/.zcash-params ]; then 37 | echo "Symlinking external zcash-params volume..." 38 | ln -s /mnt/zen/zcash-params $HOME/.zcash-params > /dev/null 2>&1 || true 39 | fi 40 | else 41 | echo "Using local zcash-params folder" 42 | mkdir -p $HOME/.zcash-params > /dev/null 2>&1 || true 43 | fi 44 | 45 | # data folder can be an external volume or created locally 46 | if [ ! -d "/mnt/zen/data" ]; then 47 | echo "Using local data folder" 48 | mkdir -p /mnt/zen/data > /dev/null 2>&1 || true 49 | else 50 | echo "Using external data volume" 51 | fi 52 | 53 | # Copy in any additional SSL trusted CA 54 | active=$(cat /mnt/zen/secnode/config.json | jq -r '.active') 55 | if [ $active == "secure" ]; then 56 | domain=$(cat /mnt/zen/secnode/config.json | jq -r '.secure.fqdn') 57 | else 58 | domain=$(cat /mnt/zen/secnode/config.json | jq -r '.super.fqdn') 59 | fi 60 | 61 | if [ -f /etc/letsencrypt/live/$domain/chain.pem ]; then 62 | echo "Copying additional trusted SSL certificates" 63 | cp /etc/letsencrypt/live/$domain/chain.pem /usr/local/share/ca-certificates/ca.crt > /dev/null 2>&1 || true 64 | update-ca-certificates --fresh 65 | elif [ -f /mnt/zen/certs/$domain/ca.cer ]; then 66 | echo "Copying additional trusted SSL certificates" 67 | cp /mnt/zen/certs/$domain/ca.cer /usr/local/share/ca-certificates/ca.crt > /dev/null 2>&1 || true 68 | update-ca-certificates --fresh 69 | fi 70 | 71 | # Fix ownership of the created files/folders 72 | chown -R user:user /home/user /mnt/zen 73 | 74 | /usr/local/bin/gosu user zen-fetch-params 75 | 76 | echo "Starting $@ .." 77 | if [[ "$1" == zend ]]; then 78 | exec /usr/local/bin/gosu user /bin/bash -c "$@ $OPTS" 79 | fi 80 | 81 | exec /usr/local/bin/gosu user "$@" 82 | -------------------------------------------------------------------------------- /ansible/README.md: -------------------------------------------------------------------------------- 1 | # Ansible Installer 2 | 3 | The ansible installer will allow you to configure multiple nodes simultaneously. 4 | 5 | If you have an existing node it will be easiest to run the installer from that node. 6 | 7 | ``` 8 | apt-get install ansible 9 | git clone https://github.com/WhenLamboMoon/docker-zen-node/ 10 | cd docker-zen-node/ansible/ 11 | ``` 12 | 13 | Configure the hosts files with your list of nodes, an example hosts file would look like this: 14 | 15 | ``` 16 | # Parameters passed to all hosts 17 | [all:vars] 18 | email=test@example.com 19 | region=na 20 | 21 | [zen-nodes] 22 | node.example.com fqdn=node.example.com stakeaddr=test nodetype=secure 23 | node2.example.com fqdn=node3.example.com stakeaddr=test nodetype=secure 24 | node3.example.com fqdn=node2.example.com stakeaddr=test nodetype=secure 25 | 26 | [bootstrap-nodes] 27 | node2.example.com 28 | node3.example.com 29 | ``` 30 | 31 | If you are running this from an existing node, jump down to the [bootstrap node](https://github.com/WhenLamboMoon/docker-zen-node/tree/master/ansible#bootstraping-the-blockchain) section 32 | to speed up node installation. 33 | 34 | Now run the installer, this will install the securenodes on all of your listed hosts. 35 | 36 | ``` 37 | ansible-playbook -i hosts main.yml 38 | ``` 39 | 40 | When the installation completes, all your installed nodes details will be stored in /tmp/zen-node-results 41 | 42 | ``` 43 | cat /tmp/zen-node-results 44 | ``` 45 | 46 | It will list results similar to this: 47 | 48 | ``` 49 | localhost: 50 | 51 | Shield Address: 52 | zcNBdJxZnhTZMdiSQABYiW1wY2A8Swrq8TsauYLiyaShKD91GrZvn1dqAkhZ8USmAHoKNxhokeoYJZwJAtKjyeWN4BMNM6v 53 | 54 | Balance: 55 | transparent: 0.00 56 | private: 0.00 57 | total: 0.00 58 | ``` 59 | 60 | You will now need to send the 1 ZEN to the shield addresses that have a balance of 0.0 61 | 62 | ### Bootstraping the blockchain 63 | 64 | *Bootstrapping currently does not work.* 65 | 66 | If you are running the installer on the same server as an existing zen-node, 67 | you can bootstrap/seed the initial blockchain to your new nodes so they can sync faster. 68 | 69 | Simply add the new nodes to your hosts inventory file as: 70 | 71 | ``` 72 | [bootstrap-nodes] 73 | new-node1.example.com 74 | new-node2.example.com 75 | ``` 76 | 77 | Now run the bootstrap playbook: 78 | 79 | ``` 80 | ansible-playbook -i hosts bootstrap.yml 81 | ``` 82 | 83 | This will copy the blockchain from your current node (running the installer) to your new nodes. After you run this, remove the nodes from the [bootstrap-nodes] group and run the full installer. 84 | 85 | ### Upgrading 86 | 87 | The installer has a handy way to update all of your zen-nodes: 88 | 89 | ``` 90 | ansible-playbook -i hosts upgrade.yml 91 | ``` 92 | 93 | This will upgrade restart the required services. It is recommended you subscribe to 94 | [announcement tracking](https://github.com/WhenLamboMoon/docker-zen-node/issues/28) to receive email notifications. 95 | 96 | ### Status 97 | 98 | You may check the status of your nodes anytime with the command: 99 | 100 | ``` 101 | ansible-playbook -i hosts status.yml 102 | ``` 103 | 104 | This will report the node name, shield address, balance and current block. 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker Zencash Secure Node 2 | 3 | **UNFORTUNATELY I AM NO LONGER ABLE TO MAINTAIN THIS DUE TO OTHER COMMITMENTS. PLEASE OPEN AN ISSUE IF YOU ARE INTERESTED IN TAKING OVER** 4 | 5 | This repository will help you setup a zencash node with a single bash script. 6 | 7 | The script will install Docker on a fresh Ubuntu VM and provision the following 8 | containers: 9 | 10 | - zend https://hub.docker.com/r/whenlambomoon/zend/ 11 | - Securenodetracker https://hub.docker.com/r/whenlambomoon/secnodetracker/ 12 | 13 | Certbot will be installed and auto-renew your SSL certificates when required. 14 | 15 | ## Requirements 16 | 17 | You will need a server with at least 4GB ram (2GB memory w/ 2GB swap is generally OK) to run a ZenCash secure node. Common providers can be found here: https://horizenofficial.atlassian.net/wiki/spaces/ZEN/pages/136872080/Community+VPS+List 18 | 19 | The script is designed to run on Ubuntu 16.04 20 | 21 | You will also need a domain name that is pointing to your server (eg. zennode.example.com) 22 | certbot will be used to provision and maintain a valid SSL certificate for your domain. 23 | 24 | ## Installation 25 | 26 | Invoking the script is best done on a fresh installation, however executing install script again should not 27 | cause any issues. 28 | 29 | *Note:* Check the [ansible installer](https://github.com/WhenLamboMoon/docker-zen-node/tree/master/ansible) if you plan on installing multiple nodes 30 | 31 | ``` 32 | curl -O https://raw.githubusercontent.com/WhenLamboMoon/docker-zen-node/master/install.sh 33 | chmod +x install.sh 34 | ./install.sh 35 | ``` 36 | 37 | - Stakeaddr is the transparent address which has your 42 ZEN 38 | - Email is your notification email address should your node have issues 39 | - FQDN is the hostname which must point to the IP address of your server 40 | - Region must either be eu or na 41 | - Nodetype is secure or super 42 | 43 | Example: 44 | 45 | `./install.sh ztjcr2DSYhMZZ3WFFeoK2hDxhmK4VP3QcgK email@example.com zennode.example.com na secure` 46 | 47 | The script will install the required dependencies and deploy the three containers on your host. 48 | 49 | The script should execute successfully when you see the output similar to this: 50 | 51 | ``` 52 | ## Generating shield address for node... 53 | 54 | ztSpgr2Yat7zSMiLNHtyDKGajzSesxabQsRwJnqtomDJU9wd6LzZppnQJyYiNE8sJDEy5MyTiMrSjf3bWcMKgtF9xcEY4eA 55 | ``` 56 | 57 | This will be the shield address you need to send 0.05 ZEN in order for your start accepting challenges. It is recommended you send this in 3 transactions of 0.0167 ZEN. As of now, this can only be done using the swing wallet or CLI. 58 | 59 | After you send your 0.05 ZEN, you may check your node private balance: 60 | 61 | ``` 62 | docker exec zen-node gosu user zen-cli z_gettotalbalance 63 | ``` 64 | 65 | The securenodetracker will only report a successful status after you've sent your ZEN to the shield address. You may check by viewing the secnodetracker logs: 66 | 67 | ``` 68 | docker logs zen-secnodetracker 69 | ``` 70 | 71 | It should return something like this: 72 | 73 | ``` 74 | Secure node config found OK - linking... 75 | CPU Intel Core Processor (Haswell, no TSX) cores=1 speed=2394 76 | Tracker app version: 0.1.0 77 | MemTotal: 3.86GB MemFree: 1.61GB MemAvailable: 3.47GB SwapTotal: 4.10GB SwapFree: 4.10GB 78 | 2017-12-01 07:29:58 GMT -- Connected to server ts1.na. Initializing... 79 | 2017-12-01 07:30:08 GMT -- Zend: Loading block index... 80 | 2017-12-01 07:30:18 GMT -- Zend: Verifying blocks... 81 | Secure Node t_address (not for stake)=XXXX 82 | Balance for challenge transactions is 1 83 | Using the following address for challenges 84 | xxxx 85 | ``` 86 | 87 | Finally, check the securenode tracker website to see if your node has been registered: 88 | 89 | - NA: https://securenodes.na.zensystem.io/ 90 | - EU: https://securenodes.eu.zensystem.io/ 91 | 92 | **Please Note:** It may take a few hours for your server to fully update to the latest block. Your node will not come online until this has been fully updated. 93 | 94 | You may check the latest block status with the following command: 95 | 96 | ``` 97 | docker exec zen-node gosu user zen-cli getinfo 98 | ``` 99 | 100 | ## Adding new nodes 101 | 102 | If you are creating multiple nodes, you may seed the initial blockchain from one of your running nodes with the following command: 103 | 104 | ``` 105 | rsync -avh --progress /mnt/zen/config/blocks /mnt/zen/config/chainstate /mnt/zen/config/database yournewnode:/mnt/zen/config/ 106 | ``` 107 | 108 | This will save you the 1-2 hours wait for a new node to download the full chain. 109 | 110 | ## Moving/removing nodes 111 | 112 | If you want to move the ZEN off the node you need to run the following commands: 113 | 114 | ``` 115 | # Get your T_ADDR 116 | docker exec -it zen-node gosu user zen-cli z_listaddresses 117 | 118 | # Get the balance of your T_ADDR 119 | docker exec -it zen-node gosu user zen-cli z_getbalance T_ADDR 120 | 121 | # Send the balance to another address 122 | docker exec zen-node gosu user zen-cli z_sendmany "T_ADDR" "[{\"amount\": 0.00, \"address\": \"TO_ZEN_ADDR\"}]" 123 | ``` 124 | 125 | Remember to deduct the 0.0001 fee from your balance if you wish to empty the entire balance. 126 | 127 | ## Troubleshooting 128 | 129 | If you need to execute commands with `zen-cli` you will need to append the following: 130 | 131 | ``` 132 | docker exec zen-node gosu user zen-cli 133 | ``` 134 | 135 | This is because zend is run as a non-root user using `gosu`. Removing `gosu user` will return 136 | you an error due to missing config files. 137 | 138 | If you run into any issues feel free to open an issue. Please include output from the following commands when opening your issue: 139 | 140 | ``` 141 | docker logs zen-secnodetracker 142 | docker logs zen-node 143 | ``` 144 | 145 | If your zen-node becomes corrupted due to lack of disk space you may see an error similar to this: 146 | 147 | ``` 148 | 2017-12-10 21:22:46 Corruption: checksum mismatch 149 | 2017-12-10 21:22:46 : Error opening block database. 150 | Please restart with -reindex to recover. 151 | 2017-12-10 21:22:46 Aborted block database rebuild. Exiting. 152 | 2017-12-10 21:22:46 scheduler thread interrupt 153 | 2017-12-10 21:22:46 Shutdown: In progress... 154 | 2017-12-10 21:22:46 StopRPC: waiting for async rpc workers to stop 155 | 2017-12-10 21:22:46 StopNode() 156 | 2017-12-10 21:22:46 Shutdown: done 157 | ``` 158 | 159 | To resolve this you will need to reindex your zen-node. To do this you will need to run the following commands: 160 | 161 | ``` 162 | systemctl stop zen-node 163 | docker run --rm --net=host -p 9033:9033 -p 18231:18231 -v /mnt/zen:/mnt/zen -v /etc/letsencrypt/:/etc/letsencrypt --name zen-node whenlambomoon/zend:latest zend -reindex 164 | ``` 165 | 166 | Once it finishes reindexing you can exit and restart the zen-node normally: 167 | 168 | ``` 169 | docker stop zen-node 170 | systemctl restart zen-node 171 | ``` 172 | 173 | ## Donations 174 | 175 | Donations are appreciated: 176 | 177 | **ETH** 0xb08c615eb6e0269dc27ece4a581f87d2f5b7188d 178 | 179 | **ZEN** znoYaPU2G7MzUA69cMSYzmqMG4rkw3Mx7ae 180 | -------------------------------------------------------------------------------- /ansible/roles/zen-node/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | 4 | - name: Creating a 4GB swap file 5 | command: fallocate -l 4G /swapfile 6 | register: write_swapfile 7 | when: ansible_memory_mb.real.total + ansible_memory_mb.swap.total < 4096 8 | ignore_errors: yes 9 | 10 | 11 | - name: Set swap file permissions 12 | file: 13 | path: /swapfile 14 | mode: 0600 15 | when: write_swapfile.changed 16 | ignore_errors: yes 17 | 18 | 19 | - name: Build swapfile 20 | command: mkswap /swapfile 21 | when: write_swapfile.changed 22 | ignore_errors: yes 23 | 24 | 25 | - name: Enable swapfile 26 | command: swapon /swapfile 27 | when: write_swapfile.changed 28 | ignore_errors: yes 29 | 30 | 31 | - name: Add swapfile to /etc/fstab 32 | lineinfile: dest=/etc/fstab line="/swapfile none swap sw 0 0" state=present 33 | when: write_swapfile.changed 34 | 35 | - name: Update all packages to the latest version 36 | apt: 37 | upgrade: dist 38 | 39 | - name: Add Certbot PPA 40 | apt_repository: 41 | repo: ppa:certbot/certbot 42 | state: present 43 | update_cache: yes 44 | 45 | - name: Install required packages 46 | apt: 47 | name: "{{ item }}" 48 | state: latest 49 | with_items: 50 | - docker.io 51 | - apt-transport-https 52 | - lsb-release 53 | - curl 54 | - fail2ban 55 | - unattended-upgrades 56 | - ufw 57 | - certbot 58 | register: install_packages 59 | 60 | 61 | - name: Start docker 62 | service: 63 | name: docker 64 | state: started 65 | enabled: yes 66 | 67 | 68 | - name: Create directories 69 | file: 70 | path: "{{ item }}" 71 | state: directory 72 | mode: 0755 73 | recurse: yes 74 | with_items: 75 | - /mnt/zen/config 76 | - /mnt/zen/data 77 | - /mnt/zen/zcash-params 78 | - /mnt/zen/certs 79 | 80 | - name: Remove acme-sh from systemd 81 | file: 82 | path: "/etc/systemd/system/acme-sh.service" 83 | state: absent 84 | register: acme 85 | 86 | - name: Disable acme-sh 87 | service: 88 | name: acme-sh 89 | state: stopped 90 | enabled: no 91 | when: acme.changed 92 | 93 | - name: "Check if certificate for {{ fqdn }} exists" 94 | stat: 95 | path: "/etc/letsencrypt/live/{{ fqdn }}/cert.pem" 96 | register: letsencrypt_cert 97 | 98 | - name: Generate new certificate if one doesn't exist. 99 | shell: "certbot certonly --standalone --noninteractive --agree-tos --email {{ cert_email }} -d {{ cert_domain }}" 100 | when: not letsencrypt_cert.stat.exists 101 | 102 | - name: Open permissions on cert directory 103 | file: 104 | path: "/etc/letsencrypt/" 105 | state: directory 106 | mode: 0755 107 | recurse: yes 108 | 109 | - name: Creating the secnode config... 110 | file: 111 | path: /mnt/zen/secnode 112 | state: directory 113 | mode: 0755 114 | recurse: yes 115 | 116 | 117 | - name: Generate random rpcpassword 118 | shell: | 119 | if [ -f /mnt/zen/secnode/rpcpassword ]; then 120 | cat /mnt/zen/secnode/rpcpassword 121 | else 122 | head -c 32 /dev/urandom | base64 123 | fi 124 | register: rpcpassword 125 | 126 | - name: Installing zen-node service 127 | template: 128 | src: zen-node.service 129 | dest: "/etc/systemd/system/zen-node.service" 130 | register: write_zen_node 131 | 132 | - name: Installing zen-secnodetracker service 133 | template: 134 | src: zen-secnodetracker.service 135 | dest: "/etc/systemd/system/zen-secnodetracker.service" 136 | register: write_zen_node_tracker 137 | 138 | - name: Install zenupdate service 139 | template: 140 | src: zenupdate.service 141 | dest: "/lib/systemd/system/zenupdate.service" 142 | register: write_zen_updater 143 | 144 | - name: Install zenupdate cron service 145 | template: 146 | src: zenupdate.timer 147 | dest: "/lib/systemd/system/zenupdate.timer" 148 | register: write_zen_timer 149 | 150 | - name: reload systemd for zen containers 151 | systemd: 152 | daemon_reload: yes 153 | when: write_zen_node.changed or write_zen_node_tracker.changed or write_zen_updater.changed or write_zen_timer.changed 154 | 155 | - name: Set the servers env 156 | set_fact: 157 | servers: "{% if nodetype=='super' %}xns{% else %}ts{% endif %}" 158 | 159 | - name: Set server public IP addresses 160 | set_fact: 161 | externalIP_list: "$(dig $fqdn A $fqdn AAAA +short) " 162 | 163 | - name: Creating the zen secnode configuration 164 | template: 165 | src: config.json.j2 166 | dest: "/mnt/zen/secnode/config.json" 167 | notify: restart_zen-secnodetracker 168 | 169 | - name: Creating the zen configuration 170 | template: 171 | src: zen.conf.j2 172 | dest: "/mnt/zen/config/zen.conf" 173 | notify: restart_zen-node 174 | 175 | - name: Enabling and starting zen-node container services... 176 | service: 177 | name: zen-node 178 | state: started 179 | enabled: yes 180 | 181 | - name: Enabling and starting zen-secnodetracker container services... 182 | service: 183 | name: zen-secnodetracker 184 | state: started 185 | enabled: yes 186 | 187 | - name: Disabling existing certbot timer... 188 | systemd: 189 | name: certbot.timer 190 | state: stopped 191 | enabled: no 192 | 193 | - name: Enabling and starting the zenupdate service... 194 | service: 195 | name: zenupdate 196 | state: started 197 | enabled: yes 198 | 199 | - name: Enabling and starting the zenupdate timer... 200 | systemd: 201 | name: zenupdate.timer 202 | state: started 203 | enabled: yes 204 | 205 | - name: Configure ufw defaults 206 | ufw: 207 | direction: "{{ item.direction }}" 208 | policy: "{{ item.policy }}" 209 | with_items: 210 | - { direction: 'incoming', policy: 'deny' } 211 | - { direction: 'outgoing', policy: 'allow' } 212 | when: install_packages.changed 213 | 214 | 215 | - name: Configure ufw rules 216 | ufw: 217 | rule: "{{ item.rule }}" 218 | port: "{{ item.port }}" 219 | proto: "{{ item.proto }}" 220 | with_items: 221 | - { rule: 'allow', port: '{{ ssh_port | default("22") }}', proto: 'tcp' } 222 | - { rule: 'limit', port: '{{ ssh_port | default("22") }}', proto: 'tcp' } 223 | - { rule: 'allow', port: '80', proto: 'tcp' } 224 | - { rule: 'allow', port: '443', proto: 'tcp' } 225 | - { rule: 'allow', port: '9033', proto: 'tcp' } 226 | when: install_packages.changed 227 | 228 | 229 | - name: ufw enable 230 | command: ufw --force enable 231 | when: install_packages.changed 232 | 233 | - name: Enabling fail2ban services... 234 | service: 235 | name: fail2ban 236 | state: started 237 | enabled: yes 238 | when: install_packages.changed 239 | 240 | 241 | - name: Waiting for node to fetch params ... 242 | command: docker exec zen-node /usr/local/bin/gosu user zen-cli getinfo 243 | register: fetch_param_result 244 | until: fetch_param_result.rc == 0 245 | retries: 100 246 | delay: 30 247 | 248 | 249 | - name: Generate shield address 250 | shell: | 251 | if [ $(docker exec zen-node /usr/local/bin/gosu user zen-cli z_listaddresses | wc -l) -eq 2 ]; then 252 | docker exec zen-node /usr/local/bin/gosu user zen-cli z_getnewaddress 253 | systemctl restart zen-secnodetracker 254 | fi 255 | 256 | - name: Get current block 257 | shell: | 258 | docker exec zen-node /usr/local/bin/gosu user zen-cli getinfo | grep \"blocks\" | tr -d \", 259 | register: zenblock 260 | 261 | - name: Get shield address 262 | shell: | 263 | docker exec zen-node /usr/local/bin/gosu user zen-cli z_listaddresses | tr -d []\"' ' 264 | register: zenshield 265 | 266 | - name: Get shield address balance 267 | shell: | 268 | docker exec zen-node /usr/local/bin/gosu user zen-cli z_gettotalbalance | tr -d {}\", 269 | register: zenbalance 270 | 271 | - set_fact: 272 | zenblock: "{{ zenblock.stdout }}" 273 | zenshield: "{{ zenshield.stdout }}" 274 | zenbalance: "{{ zenbalance.stdout }}" 275 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export DEBIAN_FRONTEND=noninteractive 4 | 5 | print_status() { 6 | echo 7 | echo "## $1" 8 | echo 9 | } 10 | 11 | if [ $# -lt 4 ]; then 12 | echo "Execution format ./install.sh stakeaddr email fqdn region nodetype" 13 | exit 14 | fi 15 | 16 | # Installation variables 17 | stakeaddr=${1} 18 | email=${2} 19 | fqdn=${3} 20 | region=${4} 21 | 22 | if [ -z "$5" ]; then 23 | nodetype="secure" 24 | else 25 | nodetype=${5} 26 | fi 27 | 28 | testnet=0 29 | rpcpassword=$(head -c 32 /dev/urandom | base64) 30 | 31 | print_status "Installing the ZenCash node..." 32 | 33 | echo "#########################" 34 | echo "fqdn: $fqdn" 35 | echo "email: $email" 36 | echo "stakeaddr: $stakeaddr" 37 | echo "#########################" 38 | 39 | # Create swapfile if less then 4GB memory 40 | totalmem=$(free -m | awk '/^Mem:/{print $2}') 41 | totalswp=$(free -m | awk '/^Swap:/{print $2}') 42 | totalm=$(($totalmem + $totalswp)) 43 | if [ $totalm -lt 4000 ]; then 44 | print_status "Server memory is less then 4GB..." 45 | if ! grep -q '/swapfile' /etc/fstab ; then 46 | print_status "Creating a 4GB swapfile..." 47 | fallocate -l 4G /swapfile 48 | chmod 600 /swapfile 49 | mkswap /swapfile 50 | swapon /swapfile 51 | echo '/swapfile none swap sw 0 0' >> /etc/fstab 52 | fi 53 | fi 54 | 55 | # Populating Cache 56 | print_status "Populating apt-get cache..." 57 | apt-get update 58 | 59 | print_status "Installing packages required for setup..." 60 | apt-get install -y docker.io apt-transport-https lsb-release curl fail2ban unattended-upgrades ufw dnsutils > /dev/null 2>&1 61 | 62 | systemctl enable docker 63 | systemctl start docker 64 | 65 | print_status "Creating the docker mount directories..." 66 | mkdir -p /mnt/zen/{config,data,zcash-params,certs} 67 | 68 | print_status "Removing acme container service..." 69 | rm /etc/systemd/system/acme-sh.service 70 | 71 | print_status "Disable apache2 if enabled, to free Port 80..." 72 | systemctl disable apache2 73 | systemctl stop apache2 74 | 75 | print_status "Installing certbot..." 76 | add-apt-repository ppa:certbot/certbot -y 77 | apt-get update -y 78 | apt-get install certbot -y 79 | 80 | print_status "Issusing cert for $fqdn..." 81 | certbot certonly -n --agree-tos --register-unsafely-without-email --standalone -d $fqdn 82 | 83 | chmod -R 755 /etc/letsencrypt/ 84 | 85 | echo \ 86 | "[Unit] 87 | Description=zenupdate.service 88 | 89 | [Service] 90 | Type=oneshot 91 | ExecStart=/usr/bin/certbot -q renew --deploy-hook 'systemctl restart zen-node && systemctl restart zen-secnodetracker && docker rmi $(docker images --quiet --filter "dangling=true")' 92 | PrivateTmp=true" | tee /lib/systemd/system/zenupdate.service 93 | 94 | echo \ 95 | "[Unit] 96 | Description=Run zenupdate unit daily @ 06:00:00 (UTC) 97 | 98 | [Timer] 99 | OnCalendar=*-*-* 06:00:00 100 | Unit=zenupdate.service 101 | Persistent=true 102 | 103 | [Install] 104 | WantedBy=timers.target" | tee /lib/systemd/system/zenupdate.timer 105 | 106 | systemctl daemon-reload 107 | systemctl stop certbot.timer 108 | systemctl disable certbot.timer 109 | 110 | systemctl start zenupdate.timer 111 | systemctl enable zenupdate.timer 112 | 113 | print_status "Creating the zen configuration." 114 | cat < /mnt/zen/config/zen.conf 115 | rpcport=18231 116 | rpcallowip=127.0.0.1 117 | rpcworkqueue=512 118 | server=1 119 | # Docker doesn't run as daemon 120 | daemon=0 121 | listen=1 122 | txindex=1 123 | logtimestamps=1 124 | ### testnet config 125 | testnet=$testnet 126 | rpcuser=user 127 | rpcpassword=$rpcpassword 128 | tlscertpath=/etc/letsencrypt/live/$fqdn/cert.pem 129 | tlskeypath=/etc/letsencrypt/live/$fqdn/privkey.pem 130 | # 131 | port=9033 132 | EOF 133 | 134 | print_status "Trying to determine public ip addresses..." 135 | publicips=$(dig $fqdn A $fqdn AAAA +short) 136 | while read -r line; do 137 | echo "externalip=$line" >> /mnt/zen/config/zen.conf 138 | done <<< "$publicips" 139 | 140 | print_status "Creating the secnode config..." 141 | 142 | if [ $nodetype = "super" ]; then 143 | servers=xns 144 | else 145 | servers=ts 146 | fi 147 | 148 | mkdir -p /mnt/zen/secnode/ 149 | cat << EOF > /mnt/zen/secnode/config.json 150 | { 151 | "active": "$nodetype", 152 | "$nodetype": { 153 | "nodetype": "$nodetype", 154 | "nodeid": null, 155 | "servers": [ 156 | "${servers}2.eu", 157 | "${servers}1.eu", 158 | "${servers}3.eu", 159 | "${servers}4.eu", 160 | "${servers}4.na", 161 | "${servers}3.na", 162 | "${servers}2.na", 163 | "${servers}1.na" 164 | ], 165 | "stakeaddr": "$stakeaddr", 166 | "email": "$email", 167 | "fqdn": "$fqdn", 168 | "ipv": "4", 169 | "region": "$region", 170 | "home": "${servers}1.$region", 171 | "category": "none" 172 | } 173 | } 174 | EOF 175 | 176 | print_status "Installing zend service..." 177 | cat < /etc/systemd/system/zen-node.service 178 | [Unit] 179 | Description=Zen Daemon Container 180 | After=docker.service 181 | Requires=docker.service 182 | 183 | [Service] 184 | TimeoutStartSec=10m 185 | Restart=always 186 | ExecStartPre=-/usr/bin/docker stop zen-node 187 | ExecStartPre=-/usr/bin/docker rm zen-node 188 | # Always pull the latest docker image 189 | ExecStartPre=/usr/bin/docker pull whenlambomoon/zend:latest 190 | ExecStart=/usr/bin/docker run --rm --net=host -p 9033:9033 -p 18231:18231 -v /mnt/zen:/mnt/zen -v /etc/letsencrypt/:/etc/letsencrypt/ --name zen-node whenlambomoon/zend:latest 191 | [Install] 192 | WantedBy=multi-user.target 193 | EOF 194 | 195 | print_status "Installing secnodetracker service..." 196 | cat < /etc/systemd/system/zen-secnodetracker.service 197 | [Unit] 198 | Description=Zen Secnodetracker Container 199 | After=docker.service 200 | Requires=docker.service 201 | 202 | [Service] 203 | TimeoutStartSec=10m 204 | Restart=always 205 | ExecStartPre=-/usr/bin/docker stop zen-secnodetracker 206 | ExecStartPre=-/usr/bin/docker rm zen-secnodetracker 207 | # Always pull the latest docker image 208 | ExecStartPre=/usr/bin/docker pull whenlambomoon/secnodetracker:latest 209 | #ExecStart=/usr/bin/docker run --init --rm --net=host -v /mnt/zen:/mnt/zen --name zen-secnodetracker whenlambomoon/secnodetracker:latest 210 | ExecStart=/usr/bin/docker run --rm --net=host -v /mnt/zen:/mnt/zen --name zen-secnodetracker whenlambomoon/secnodetracker:latest 211 | [Install] 212 | WantedBy=multi-user.target 213 | EOF 214 | 215 | print_status "Enabling and starting container services..." 216 | systemctl daemon-reload 217 | systemctl enable zen-node 218 | systemctl restart zen-node 219 | 220 | systemctl enable zen-secnodetracker 221 | systemctl restart zen-secnodetracker 222 | 223 | print_status "Enabling basic firewall services..." 224 | ufw default allow outgoing 225 | ufw default deny incoming 226 | ufw allow ssh/tcp 227 | ufw limit ssh/tcp 228 | ufw allow http/tcp 229 | ufw allow https/tcp 230 | ufw allow 9033/tcp 231 | #ufw allow 19033/tcp 232 | ufw --force enable 233 | 234 | print_status "Enabling fail2ban services..." 235 | systemctl enable fail2ban 236 | systemctl start fail2ban 237 | 238 | print_status "Waiting for node to fetch params ..." 239 | until docker exec -it zen-node /usr/local/bin/gosu user zen-cli getinfo 240 | do 241 | echo ".." 242 | sleep 30 243 | done 244 | 245 | if [[ $(docker exec -it zen-node /usr/local/bin/gosu user zen-cli z_listaddresses | wc -l) -eq 2 ]]; then 246 | print_status "Generating shield address for node... you will need to send 1 ZEN to this address:" 247 | docker exec -it zen-node /usr/local/bin/gosu user zen-cli z_getnewaddress 248 | 249 | print_status "Restarting secnodetracker" 250 | systemctl restart zen-secnodetracker 251 | else 252 | print_status "Node already has shield address... you will need to send 1 ZEN to this address:" 253 | docker exec -it zen-node /usr/local/bin/gosu user zen-cli z_listaddresses 254 | fi 255 | 256 | print_status "Install Finished" 257 | echo "Please wait until the blocks are up to date..." 258 | 259 | ## TODO: Post the shield address back to our API 260 | --------------------------------------------------------------------------------