# Setup HTTPS for Grin Wallet in Ubuntu and Apache

**URL:** <https://forum.grin.mw/t/setup-https-for-grin-wallet-in-ubuntu-and-apache/7174>\
**Category:** Development and Technical Discussion\
**Created:** [March 25, 2020, 3:49pm UTC](https://forum.grin.mw/t/setup-https-for-grin-wallet-in-ubuntu-and-apache/7174 "2020-03-25T15:49:43Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![noobvie](https://avatars.discourse-cdn.com/v4/letter/n/9d8465/32.png) [@noobvie](https://forum.grin.mw/u/noobvie)\
**Post date:** [March 25, 2020, 3:49pm UTC](https://forum.grin.mw/t/setup-https-for-grin-wallet-in-ubuntu-and-apache/7174/1 "2020-03-25T15:49:43Z")

</div>

Today I’d like to share my own struggling experience to build my HTTPS Grin wallet with certified encrypted SSL certificate.

**Preprequisites:**

Assume that you are **running a Grin node and Grin wallet listening on port 3415 in Ubuntu**. And your HTTP wallet could receive Grin well from other wallets.  
**—This part is to help new users to run Grin node & wallet with least efforts—**  
**Build a server for Grin node in Google Cloud**

After you finish to register an account for Cloud service, please click on the link to get Cloud Shell: [Cloud Shell &nbsp;|&nbsp; Google Cloud](https://cloud.google.com/shell/), click on ‘Launch Cloud Shell’.

Enter following command, or copy and paste (Control +Shift + V)

`gcloud beta compute instances create grin-gg1 --zone=us-central1-b --machine-type=f1-micro --tags=grin-gg --image=ubuntu-1804-bionic-v20190530 --image-project=ubuntu-os-cloud --boot-disk-size=30GB --boot-disk-type=pd-standard --boot-disk-device-name=grin-disk1`

You can switch 3 free zone locations:

- 1 non-preemptible f1-micro VM instance per month in one of the following US regions:
  - Oregon: us-west1
  - Iowa: us-central1
  - South Carolina: us-east1

And you could change the OS image like Debian-9 which you want by command in cloud shell:

`gcloud beta compute images list`

You have just created a new [Cloud Compute Instances](https://console.cloud.google.com/compute/instances) named grin-gg1. Click on SSH button you will be able to open the terminal

**Prepare the server for Grin node installation**

Enter following command to update and install some tools, you will have to enter the ‘Y’ to confirm the steps

`sudo apt-get update; sudo apt-get install git nano tmux pkg-config; sudo apt-get install clang cmake libncurses5-dev libncursesw5-dev zlib1g-dev libssl-dev`

Install rust:

`curl https://sh.rustup.rs -sSf | sh; source $HOME/.cargo/env`

Enter ‘1’ for default installation.

Clone grin and build a release version

```
git clone https://github.com/mimblewimble/grin.git

cd grin

cargo build --release

```

The process could take an hour, so you could open second terminal to download Grin node and Grin wallet.

- Grin node: [Releases · mimblewimble/grin · GitHub](https://github.com/mimblewimble/grin/releases)
- Grin wallet: [Releases · mimblewimble/grin-wallet · GitHub](https://github.com/mimblewimble/grin-wallet/releases)

We will use wget to download those files in home directory

```
cd ~

wget https://github.com/mimblewimble/grin/releases/download/v3.1.0/grin-v3.1.0-linux-amd64.tar.gz

wget https://github.com/mimblewimble/grin-wallet/releases/download/v3.1.1/grin-wallet-v3.1.1-linux-amd64.tar.gz

tar -xvf grin-v3.1.0-linux-amd64.tar.gz

tar -xvf grin-wallet-v3.1.1-linux-amd64.tar.gz

```

We will use command **tmux** to open 3 sessions, one session is for Grin node running in background, second terminal is for Grin wallet to run in background to listening the port to receive Grin from other people. The third one is for doing some other commands.

```
tmux new -s grinrun
tmux new -s walletlisten
tmux new -s commands

```

In tmux GUI, you could use keyboard combination

- Control+b-s to list sessions
- Control+b-d to detach the session to normal bash GUI

tmux attach -t : to open the session you want

**Start to run Grin node mainnet, in session named grinrun:**

```
tmux new -s grinrun

cd ~

cd grin/

./grin

```

**Start Grin Wallet to listen the port:**

```
tmux new -s walletlisten

cd ~

cd grin-wallet/

./grin-wallet init ***#Enter your own password, remember to backup the seed (recovery phrase)!***

./grin-wallet -e listen

```

**Change the configuration of Grin node and Grin wallet:**

```
cd ~

cd .grin/main

```

Change Grin node configuration:

`nano grin-server.toml`

Change the entry to **api\_http\_addr = “0.0.0.0:3413”**

Change Grin Wallet configuration:

`nano ~/grin-wallet/grin-wallet.toml`

Change the entry to **api\_listen\_interface = “0.0.0.0”**

After changing the configuration, restart the Grin node and Grin wallet listening in tmux sessions.

**Allow Grin node and Grin wallet ports open to the internet**

Go to Google Shell, copy following commands and paste (Contrl+Shift+V)

```
gcloud compute firewall-rules create main-wallet-port -direction=INGRESS -action=ALLOW -rules=tcp:3415 -target-tags=grin-gg

gcloud compute firewall-rules create main-api-port -direction=INGRESS -action=ALLOW -rules=tcp:3413 -target-tags=grin-gg

gcloud compute firewall-rules create main-p2p-port -direction=INGRESS -action=ALLOW -rules=tcp:3414 -target-tags=grin-gg

gcloud compute firewall-rules create floo-wallet-port -direction=INGRESS -action=ALLOW -rules=tcp:13415 -target-tags=grin-gg

```

Or you could manually create firewall rules by user graphic in webpage:

Check the current ports open in your server, use command below:

netstat -na|grep 0.0.0.0

The output will look like:

tcp 0 0 0.0.0.0:3413 0.0.0.0:\* LISTEN  
tcp 0 0 0.0.0.0:3414 0.0.0.0:\* LISTEN  
tcp 0 0 0.0.0.0:22 0.0.0.0:\* LISTEN  
tcp 0 0 0.0.0.0:3415 0.0.0.0:\* LISTEN

Now your ports are open and will be able to accessed by people around the world, and your wallet is accepting $GRIN like http://your\_ip\_address:3415

—End of Grin node & wallet installation part—

**Technical Idea**

I’m just a newbie, maybe I do not explain well but hope it helps someone new in this system administration. Expert! please comment/or correct if what I explained is wrong. Thanks in advance.

**HTTP GRIN wallet:**

- Your GRIN wallet listening port 3415 \<———\> protocol HTTP \<———\> Internet wallets

**HTTPs GRIN wallet:**

- Your GRIN wallet listening port 3415 \<———\> SSL Proxy by Apache \<———\> protocol HTTPs \<———\> Internet wallets

So for HTTPS, we have to install Reverse Proxy for SSL service, we could use self-signed certificate but not recommend. We could use certified Let’s Encrypt certificate for free.

**Install Apache and Mods**

```
sudo apt-get install apache2
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo systemctl restart apache2

```

**Whitelist the ports in your server**

```
sudo ufw allow http
sudo ufw allow https

```

`sudo ufw allow proto tcp from any to any port 3413,3414,3415`

**Allow ports in Amazon AWS**

Identify the Security group associated with your node, edit the firewall rule in Amazon EC2  
 ![image](https://canada1.discourse-cdn.com/flex036/uploads/grin/original/2X/c/cddcfd8f390493d154a3c4c0d8996f7ab7ee4b43.png)

**Install certified SSL with Let’s Encrypt**

```
sudo wget https://dl.eff.org/certbot-auto -O /usr/sbin/certbot-auto
sudo chmod a+x /usr/sbin/certbot-auto

sudo certbot-auto --apache -d grin.yourdomain.com

```

![image](https://canada1.discourse-cdn.com/flex036/uploads/grin/original/2X/1/12c9cbaa1e45be6d8e4fb833b8c19ecdfce3405c.png)  
**Change the Apache Configuration**

`mkdir -p /etc/apache2/log/`

`sudo nano /etc/apache2/sites-available/000-default-le-ssl.conf`

```
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName grin.yourdomain.com
ServerAdmin your_email@email.com
DocumentRoot /var/www/html
<Directory /var/www/html>
Options FollowSymLinks
AllowOverride All
Allow from all
</Directory>
LogLevel notice
ErrorLog /etc/apache2/log/grin-error.log
CustomLog /etc/apache2/log/grin-access.log combined
SSLEngine on
SSLStrictSNIVHostCheck On
SSLCipherSuite ECDH+AESGCM,DH+AESGCM,ECDH+AES256,DH+AES256,ECDH+AES128,DH+AES,ECDH+3DES,DH+3DES,RSA+AESGCM,RSA+AES,RSA+3DES,!aNULL,!MD5,!DSS
SSLHonorCipherOrder on
SSLProtocol all -SSLv2 -SSLv3
<FilesMatch “\.(cgi|shtml|phtml|php)$”>
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
BrowserMatch “MSIE [2-6]” nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
BrowserMatch “MSIE [17-9]” ssl-unclean-shutdown
SSLCertificateFile /etc/letsencrypt/live/grin.yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/grin.yourdomain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLProxyEngine On
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3415/
ProxyPassReverse / http://127.0.0.1:3415/
</VirtualHost>
</IfModule>

```

Remember the “/” at the end of the port 3415, otherwise you will have following **error** in grin-error.log

> [Fri Jun 10 17:32:48.244509 2019] [proxy:error] [pid 12212:tid 140660153763584] [client \<source\_ip\_wallet\>:56442] AH00898: DNS lookup failure for: 127.0.0.1:3415v1 returned by /v1/wallet/foreign/receive\_tx

And grin-access.log will show return code HTTP 502

> \<source\_ip\_wallet\> - - [10/Jun/2019:17:32:48 +0000] “POST /v1/wallet/foreign/receive\_tx HTTP/1.1” **502** 3954 “-” “grin-client”

Restart Apache Service:

`sudo systemctl restart apache2`

**Auto review SSL Certificate:**

`crontab -e`

> 0 2 \* \* \* sudo /usr/sbin/certbot-auto -q renew

**Testing your HTTPs Grin Wallet**

Now your HTTPs wallet should be like: **https** ://grin.yourdomain.com **(without port)** because your HTTPs listening to port 443 by default, when GRIN sent to your wallet, it redirects to [http://127.0.0.1:3415/](http://127.0.0.1:3415/) as your wallet listening.

Here is my test in my own server:

**(In source wallet I will send 0.1 GRIN to [https://grin.anonymous.cash](https://grin.anonymous.cash))**  
 ![image](https://canada1.discourse-cdn.com/flex036/uploads/grin/original/2X/0/01414fb04025cf289c79bd07ec2a2c437ecffef3.jpeg)  
 ![image](https://canada1.discourse-cdn.com/flex036/uploads/grin/original/2X/8/8db178c2761df9bcc8d2f64e3a011a69076be93d.jpeg)  
Sender will be charged default fee 0.008 GRIN

**(In target wallet we should see the Shared Transaction Id as same as source wallet)**  
 ![image](https://canada1.discourse-cdn.com/flex036/uploads/grin/original/2X/6/6b01c9764be69352ba9d1a1f9098899bf55bd282.png)  
There will be no error message in grin-error.log, and grin-access.log will show return code HTTP 200 as below:

`<source_ip_wallet> - - [11/Jun/2019:01:02:32 +0000] "POST /v1/wallet/foreign/receive_tx HTTP/1.1" **200** 10263 "-" "grin-client"`

**Test to withdraw GRIN from the crypto exchange [Poloniex.com](http://Poloniex.com)**  
 ![image](https://canada1.discourse-cdn.com/flex036/uploads/grin/original/2X/b/b7b9d94e661171ef13b0a57fcf627fc2d2c15229.png)  
 ![image](https://canada1.discourse-cdn.com/flex036/uploads/grin/original/2X/3/330ff611cfef91316f6da32ca641666ffebf0f0f.png)

( **DON’T FORGET:** Only send 0.1 Grin to test your https wallet first, then send big amount)

---

<div class="post-metadata">

**Author:** ![mcm-mike](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.grin.mw/mcm-mike/32/3492_2.png) [@mcm-mike](https://forum.grin.mw/u/mcm-mike)\
**Post date:** [March 25, 2020, 4:27pm UTC](https://forum.grin.mw/t/setup-https-for-grin-wallet-in-ubuntu-and-apache/7174/2 "2020-03-25T16:27:12Z")

</div>

Well done !  
Make sure you mention to start your grin-wallet listener after setting everything up like in `tmux` or `screen` More comments later 🙂

---

<div class="post-metadata">

**Author:** ![david](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.grin.mw/david/32/660_2.png) [@david](https://forum.grin.mw/u/david)\
**Post date:** [March 25, 2020, 4:27pm UTC](https://forum.grin.mw/t/setup-https-for-grin-wallet-in-ubuntu-and-apache/7174/3 "2020-03-25T16:27:48Z")

</div>

> [@noobvie](#):
>
> Only send 0.1 Grin to test your https wallet first, then send big amount

@tromp - It looks like this behavior isn’t exclusive to non-interactive txs. It appears people don’t trust interactive txs either 😂

---

<div class="post-metadata">

**Author:** ![david](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.grin.mw/david/32/660_2.png) [@david](https://forum.grin.mw/u/david)\
**Post date:** [March 25, 2020, 4:29pm UTC](https://forum.grin.mw/t/setup-https-for-grin-wallet-in-ubuntu-and-apache/7174/4 "2020-03-25T16:29:12Z")

</div>

Very nice write-up! Thanks for sharing.

---

<div class="post-metadata">

**Author:** ![mcm-mike](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.grin.mw/mcm-mike/32/3492_2.png) [@mcm-mike](https://forum.grin.mw/u/mcm-mike)\
**Post date:** [March 25, 2020, 4:41pm UTC](https://forum.grin.mw/t/setup-https-for-grin-wallet-in-ubuntu-and-apache/7174/5 "2020-03-25T16:41:35Z")

</div>

> [@noobvie](#):
>
> SSLProxyEngine On  
> ProxyPreserveHost On  
> ProxyPass / [http://127.0.0.1:3415](http://127.0.0.1:3415) **/**  
> ProxyPassReverse / [http://127.0.0.1:3415](http://127.0.0.1:3415) **/**

There is a space after the IP:port in your `ProxyPass` which should not be there.  
Based on [mod\_proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html) there should be no space. If someone would just copy&past it and change `ServerName` and `SSLCertificateFile` it would not work.

```
SSLProxyEngine On
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3415/
ProxyPassReverse / http://127.0.0.1:3415/

```

Use the pre-formatted tag here should solve the problem. 🙂

---

<div class="post-metadata">

**Author:** ![noobvie](https://avatars.discourse-cdn.com/v4/letter/n/9d8465/32.png) [@noobvie](https://forum.grin.mw/u/noobvie)\
**Post date:** [March 27, 2020, 9:05am UTC](https://forum.grin.mw/t/setup-https-for-grin-wallet-in-ubuntu-and-apache/7174/6 "2020-03-27T09:05:03Z")

</div>

Thanks for your notice, at first I made my procedure with Word, some characters are automatically formatted. I corrected them as your recommended.

---

<div class="post-metadata">

**Author:** ![pinoli](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.grin.mw/pinoli/32/24_2.png) [@pinoli](https://forum.grin.mw/u/pinoli)\
**Post date:** [January 10, 2021, 3:44am UTC](https://forum.grin.mw/t/setup-https-for-grin-wallet-in-ubuntu-and-apache/7174/7 "2021-01-10T03:44:21Z")

</div>

thank you very much, I stole the bit on allowing TLS for the wallet and adapted it for my node, since I want to use my own `grin` 5.0.1 node with the [Ironbelly iOS app](https://ironbelly.app/) over HTTPS.  
Just wanted to check a couple a things with you:

- I disallowed `http` from `ufw` and it seems to still work perfectly. I’d rather not open any unnecessary ports.
- Can you confirm that by using `apache2` in this way, there is no need to set the specific TLS settings inside `grin-server.toml`? the following bits

```auto
    #path of TLS certificate file, self-signed certificates are not supported
    #tls_certificate_file = ""
    #private key for the TLS certificate
    #tls_certificate_key = ""

```

- this is generic, not strictly related to your guide. I see that Ironbelly asks for a grin node URL and a secret. It works with my HTTPS url and the secret found in `.api_secret`. Yet I see grinnode.live works without asking any secret. I would like to know how the Secret for the grin node plays a part in security, and when I should consider removing it. I might point some friends to this node in the future.

Thanks for the great work, it took me 5 minutes to setup TLS (even though I had to use `snapd` to install `certbot` since your way is deprecated on Debian 10 Buster, I followed [this guide here](https://certbot.eff.org/lets-encrypt/debianbuster-apache))
