├── tor.gpg ├── software-update.yml ├── ghost-nginx-config.template ├── README.md ├── provision.yml ├── ghost-app-config.js.template └── torrc.template /tor.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brianloveswords/onion-ghost-blog/HEAD/tor.gpg -------------------------------------------------------------------------------- /software-update.yml: -------------------------------------------------------------------------------- 1 | - hosts: all 2 | user: root 3 | gather_facts: no 4 | tasks: 5 | - name: upgrade system packages 6 | apt: update_cache=yes upgrade=yes 7 | -------------------------------------------------------------------------------- /ghost-nginx-config.template: -------------------------------------------------------------------------------- 1 | server { 2 | listen 127.0.0.1:80 default_server; 3 | 4 | server_name {{onion_hostname.stdout}}; 5 | 6 | root /usr/share/nginx/html; 7 | index index.html index.htm; 8 | 9 | client_max_body_size 10G; 10 | 11 | location / { 12 | proxy_pass http://localhost:2368; 13 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 14 | proxy_set_header Host $http_host; 15 | proxy_set_header X-Forwarded-Proto $scheme; 16 | proxy_buffering off; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # onion-ghost-blog 2 | 3 | Set up secret [Ghost](https://ghost.org/) blog on the [Tor network](https://www.torproject.org/) in under two minutes. 4 | 5 | ## What? 6 | 7 | This uses ansible (a piece of software specifically for provisioning servers) to configure a Digital Ocean Ghost image for use on the Tor network. 8 | 9 | This is based on a the [I Will Follow You into The Dark[net] presentation](https://docs.google.com/presentation/d/1A-0bggHr8fk0_UJhm251-GfyYShU0II3KNRDt9-uzjU) given at [Radical Networks 2015](http://radicalnetworks.org/) by [@carolinesinders](http://twitter.com/@carolinesinders), [@corcra](http://twitter.com/@corcra), and [@huertanix](http://twitter.com/@huertanix). 10 | 11 | ## Usage 12 | 13 | 14 | 1. Install [`ansible`](https://docs.ansible.com/ansible/intro_installation.html). On OS X, 15 | 16 | ```bash 17 | $ brew install ansible 18 | ``` 19 | 20 | For other operating systems [follow the instructions on the ansible site](https://docs.ansible.com/ansible/intro_installation.html). 21 | 22 | 1. Use [Digital Ocean](https://cloud.digitalocean.com/droplets/new) to spin up a new server pre-imaged with Ghost 23 | ![screenshot](https://cldup.com/cP-Ph2Xhh4.png) 24 | 25 | Make sure to associate your SSH key with it (my computer is called "Unicron") 26 | ![screenshot](https://cldup.com/BwnHWayr5y.png) 27 | 28 | 29 | 1. Figure out the server IP address. You can get it from the [droplet list page](https://cloud.digitalocean.com/droplets) 30 | ![screenshot](https://cldup.com/72AYhOBzsz.png) 31 | 32 | 33 | 1. Clone this repository 34 | ```bash 35 | $ git clone https://github.com/brianloveswords/onion-ghost-blog.git && cd onion-ghost-blog 36 | ``` 37 | 38 | 1. Run the ansible command 39 | 40 | ```bash 41 | # Notice the trailing comma, that is not a typo 42 | $ ansible-playbook provision.yml -i , 43 | ``` 44 | 45 | 1. 👻 The last output of the ansible run will have your Onion hostname. 👻 46 | ![screenshot](https://cldup.com/_pegX68UuB.png) 47 | -------------------------------------------------------------------------------- /provision.yml: -------------------------------------------------------------------------------- 1 | - hosts: all 2 | user: root 3 | gather_facts: no 4 | tasks: 5 | - name: gpg key downloaded 6 | command: gpg --keyserver keys.gnupg.net --recv 886DDD89 7 | 8 | - name: gpg key added 9 | shell: gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key add - 10 | 11 | - name: tor repo exists 12 | apt_repository: 13 | repo='deb http://deb.torproject.org/torproject.org trusty main' 14 | state=present 15 | 16 | - name: tor source repo exists 17 | apt_repository: 18 | repo='deb-src http://deb.torproject.org/torproject.org trusty main' 19 | state=present 20 | 21 | - name: update apt cache 22 | apt: cache_valid_time=600 update_cache=yes 23 | 24 | - name: tor is present 25 | apt: pkg="tor" state=present 26 | 27 | - name: deb.torproject.org-keyring is present 28 | apt: pkg="deb.torproject.org-keyring" state=present 29 | 30 | - name: exim is not present 31 | apt: pkg=exim state=absent 32 | 33 | - name: postfix is not present 34 | apt: pkg=postfix state=absent 35 | 36 | - name: sendmail is not present 37 | apt: pkg=sendmail state=absent 38 | 39 | - name: ufw is present 40 | apt: pkg=ufw state=present 41 | 42 | - name: ufw allow http 43 | command: /usr/sbin/ufw allow 80/tcp 44 | 45 | - name: ufw allow ssh 46 | command: /usr/sbin/ufw allow 22/tcp 47 | 48 | - name: ufw is enabled 49 | shell: echo 'y' | ufw enable 50 | 51 | - name: use correct tor config 52 | template: 53 | dest=/etc/tor/torrc 54 | src=torrc.template 55 | 56 | - name: restart tor service 57 | service: name=tor state=restarted 58 | 59 | - name: get onion hostname 60 | command: /bin/cat /var/lib/tor/hidden_service/hostname 61 | register: onion_hostname 62 | 63 | - name: use correct nginx configuration 64 | template: 65 | dest=/etc/nginx/sites-available/ghost 66 | src=ghost-nginx-config.template 67 | 68 | - name: ghost is configured for correct hostname 69 | template: 70 | dest=/var/www/ghost/config.js 71 | src=ghost-app-config.js.template 72 | 73 | - name: restart nginx 74 | service: name=nginx state=restarted 75 | 76 | - debug: msg="onion hostname is {{onion_hostname.stdout}}" 77 | -------------------------------------------------------------------------------- /ghost-app-config.js.template: -------------------------------------------------------------------------------- 1 | // # Ghost Configuration 2 | // Setup your Ghost install for various [environments](http://support.ghost.org/config/#about-environments). 3 | 4 | // Ghost runs in `development` mode by default. Full documentation can be found at http://support.ghost.org/config/ 5 | 6 | var path = require('path'), 7 | config; 8 | 9 | config = { 10 | // ### Production 11 | // When running Ghost in the wild, use the production environment. 12 | // Configure your URL and mail settings here 13 | production: { 14 | url: '{{ onion_hostname.stdout }}', 15 | mail: {}, 16 | database: { 17 | client: 'sqlite3', 18 | connection: { 19 | filename: path.join(__dirname, '/content/data/ghost.db') 20 | }, 21 | debug: false 22 | }, 23 | 24 | server: { 25 | host: '127.0.0.1', 26 | port: '2368' 27 | } 28 | }, 29 | 30 | // ### Development **(default)** 31 | development: { 32 | // The url to use when providing links to the site, E.g. in RSS and email. 33 | // Change this to your Ghost blog's published URL. 34 | url: 'http://localhost:2368', 35 | 36 | // Example mail config 37 | // Visit http://support.ghost.org/mail for instructions 38 | // ``` 39 | // mail: { 40 | // transport: 'SMTP', 41 | // options: { 42 | // service: 'Mailgun', 43 | // auth: { 44 | // user: '', // mailgun username 45 | // pass: '' // mailgun password 46 | // } 47 | // } 48 | // }, 49 | // ``` 50 | 51 | // #### Database 52 | // Ghost supports sqlite3 (default), MySQL & PostgreSQL 53 | database: { 54 | client: 'sqlite3', 55 | connection: { 56 | filename: path.join(__dirname, '/content/data/ghost-dev.db') 57 | }, 58 | debug: false 59 | }, 60 | // #### Server 61 | // Can be host & port (default), or socket 62 | server: { 63 | // Host to be passed to node's `net.Server#listen()` 64 | host: '127.0.0.1', 65 | // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT` 66 | port: '2368' 67 | }, 68 | // #### Paths 69 | // Specify where your content directory lives 70 | paths: { 71 | contentPath: path.join(__dirname, '/content/') 72 | } 73 | }, 74 | 75 | // **Developers only need to edit below here** 76 | 77 | // ### Testing 78 | // Used when developing Ghost to run tests and check the health of Ghost 79 | // Uses a different port number 80 | testing: { 81 | url: 'http://127.0.0.1:2369', 82 | database: { 83 | client: 'sqlite3', 84 | connection: { 85 | filename: path.join(__dirname, '/content/data/ghost-test.db') 86 | } 87 | }, 88 | server: { 89 | host: '127.0.0.1', 90 | port: '2369' 91 | }, 92 | logging: false 93 | }, 94 | 95 | // ### Testing MySQL 96 | // Used by Travis - Automated testing run through GitHub 97 | 'testing-mysql': { 98 | url: 'http://127.0.0.1:2369', 99 | database: { 100 | client: 'mysql', 101 | connection: { 102 | host : '127.0.0.1', 103 | user : 'root', 104 | password : '', 105 | database : 'ghost_testing', 106 | charset : 'utf8' 107 | } 108 | }, 109 | server: { 110 | host: '127.0.0.1', 111 | port: '2369' 112 | }, 113 | logging: false 114 | }, 115 | 116 | // ### Testing pg 117 | // Used by Travis - Automated testing run through GitHub 118 | 'testing-pg': { 119 | url: 'http://127.0.0.1:2369', 120 | database: { 121 | client: 'pg', 122 | connection: { 123 | host : '127.0.0.1', 124 | user : 'postgres', 125 | password : '', 126 | database : 'ghost_testing', 127 | charset : 'utf8' 128 | } 129 | }, 130 | server: { 131 | host: '127.0.0.1', 132 | port: '2369' 133 | }, 134 | logging: false 135 | } 136 | }; 137 | 138 | module.exports = config; 139 | -------------------------------------------------------------------------------- /torrc.template: -------------------------------------------------------------------------------- 1 | ## Configuration file for a typical Tor user 2 | ## Last updated 2 September 2014 for Tor 0.2.6.1-alpha. 3 | ## (may or may not work for much older or much newer versions of Tor.) 4 | ## 5 | ## Lines that begin with "## " try to explain what's going on. Lines 6 | ## that begin with just "#" are disabled commands: you can enable them 7 | ## by removing the "#" symbol. 8 | ## 9 | ## See 'man tor', or https://www.torproject.org/docs/tor-manual.html, 10 | ## for more options you can use in this file. 11 | ## 12 | ## Tor will look for this file in various places based on your platform: 13 | ## https://www.torproject.org/docs/faq#torrc 14 | 15 | ## Tor opens a socks proxy on port 9050 by default -- even if you don't 16 | ## configure one below. Set "SocksPort 0" if you plan to run Tor only 17 | ## as a relay, and not make any local application connections yourself. 18 | #SocksPort 9050 # Default: Bind to localhost:9050 for local connections. 19 | #SocksPort 192.168.0.1:9100 # Bind to this address:port too. 20 | 21 | ## Entry policies to allow/deny SOCKS requests based on IP address. 22 | ## First entry that matches wins. If no SocksPolicy is set, we accept 23 | ## all (and only) requests that reach a SocksPort. Untrusted users who 24 | ## can access your SocksPort may be able to learn about the connections 25 | ## you make. 26 | #SocksPolicy accept 192.168.0.0/16 27 | #SocksPolicy reject * 28 | 29 | ## Logs go to stdout at level "notice" unless redirected by something 30 | ## else, like one of the below lines. You can have as many Log lines as 31 | ## you want. 32 | ## 33 | ## We advise using "notice" in most cases, since anything more verbose 34 | ## may provide sensitive information to an attacker who obtains the logs. 35 | ## 36 | ## Send all messages of level 'notice' or higher to /var/log/tor/notices.log 37 | #Log notice file /var/log/tor/notices.log 38 | ## Send every possible message to /var/log/tor/debug.log 39 | #Log debug file /var/log/tor/debug.log 40 | ## Use the system log instead of Tor's logfiles 41 | #Log notice syslog 42 | ## To send all messages to stderr: 43 | #Log debug stderr 44 | 45 | ## Uncomment this to start the process in the background... or use 46 | ## --runasdaemon 1 on the command line. This is ignored on Windows; 47 | ## see the FAQ entry if you want Tor to run as an NT service. 48 | #RunAsDaemon 1 49 | 50 | ## The directory for keeping all the keys/etc. By default, we store 51 | ## things in $HOME/.tor on Unix, and in Application Data\tor on Windows. 52 | DataDirectory /var/lib/tor 53 | 54 | ## The port on which Tor will listen for local connections from Tor 55 | ## controller applications, as documented in control-spec.txt. 56 | #ControlPort 9051 57 | ## If you enable the controlport, be sure to enable one of these 58 | ## authentication methods, to prevent attackers from accessing it. 59 | #HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C 60 | #CookieAuthentication 1 61 | 62 | ############### This section is just for location-hidden services ### 63 | 64 | ## Once you have configured a hidden service, you can look at the 65 | ## contents of the file ".../hidden_service/hostname" for the address 66 | ## to tell people. 67 | ## 68 | ## HiddenServicePort x y:z says to redirect requests on port x to the 69 | ## address y:z. 70 | 71 | HiddenServiceDir /var/lib/tor/hidden_service/ 72 | HiddenServicePort 80 127.0.0.1:80 73 | 74 | #HiddenServiceDir /var/lib/tor/other_hidden_service/ 75 | #HiddenServicePort 80 127.0.0.1:80 76 | #HiddenServicePort 22 127.0.0.1:22 77 | 78 | ################ This section is just for relays ##################### 79 | # 80 | ## See https://www.torproject.org/docs/tor-doc-relay for details. 81 | 82 | ## Required: what port to advertise for incoming Tor connections. 83 | #ORPort 9001 84 | ## If you want to listen on a port other than the one advertised in 85 | ## ORPort (e.g. to advertise 443 but bind to 9090), you can do it as 86 | ## follows. You'll need to do ipchains or other port forwarding 87 | ## yourself to make this work. 88 | #ORPort 443 NoListen 89 | #ORPort 127.0.0.1:9090 NoAdvertise 90 | 91 | ## The IP address or full DNS name for incoming connections to your 92 | ## relay. Leave commented out and Tor will guess. 93 | #Address noname.example.com 94 | 95 | ## If you have multiple network interfaces, you can specify one for 96 | ## outgoing traffic to use. 97 | # OutboundBindAddress 10.0.0.5 98 | 99 | ## A handle for your relay, so people don't have to refer to it by key. 100 | #Nickname ididnteditheconfig 101 | 102 | ## Define these to limit how much relayed traffic you will allow. Your 103 | ## own traffic is still unthrottled. Note that RelayBandwidthRate must 104 | ## be at least 20 kilobytes per second. 105 | ## Note that units for these config options are bytes (per second), not 106 | ## bits (per second), and that prefixes are binary prefixes, i.e. 2^10, 107 | ## 2^20, etc. 108 | #RelayBandwidthRate 100 KBytes # Throttle traffic to 100KB/s (800Kbps) 109 | #RelayBandwidthBurst 200 KBytes # But allow bursts up to 200KB (1600Kb) 110 | 111 | ## Use these to restrict the maximum traffic per day, week, or month. 112 | ## Note that this threshold applies separately to sent and received bytes, 113 | ## not to their sum: setting "4 GB" may allow up to 8 GB total before 114 | ## hibernating. 115 | ## 116 | ## Set a maximum of 4 gigabytes each way per period. 117 | #AccountingMax 4 GBytes 118 | ## Each period starts daily at midnight (AccountingMax is per day) 119 | #AccountingStart day 00:00 120 | ## Each period starts on the 3rd of the month at 15:00 (AccountingMax 121 | ## is per month) 122 | #AccountingStart month 3 15:00 123 | 124 | ## Administrative contact information for this relay or bridge. This line 125 | ## can be used to contact you if your relay or bridge is misconfigured or 126 | ## something else goes wrong. Note that we archive and publish all 127 | ## descriptors containing these lines and that Google indexes them, so 128 | ## spammers might also collect them. You may want to obscure the fact that 129 | ## it's an email address and/or generate a new address for this purpose. 130 | #ContactInfo Random Person 131 | ## You might also include your PGP or GPG fingerprint if you have one: 132 | #ContactInfo 0xFFFFFFFF Random Person 133 | 134 | ## Uncomment this to mirror directory information for others. Please do 135 | ## if you have enough bandwidth. 136 | #DirPort 9030 # what port to advertise for directory connections 137 | ## If you want to listen on a port other than the one advertised in 138 | ## DirPort (e.g. to advertise 80 but bind to 9091), you can do it as 139 | ## follows. below too. You'll need to do ipchains or other port 140 | ## forwarding yourself to make this work. 141 | #DirPort 80 NoListen 142 | #DirPort 127.0.0.1:9091 NoAdvertise 143 | ## Uncomment to return an arbitrary blob of html on your DirPort. Now you 144 | ## can explain what Tor is if anybody wonders why your IP address is 145 | ## contacting them. See contrib/tor-exit-notice.html in Tor's source 146 | ## distribution for a sample. 147 | #DirPortFrontPage /etc/tor/tor-exit-notice.html 148 | 149 | ## Uncomment this if you run more than one Tor relay, and add the identity 150 | ## key fingerprint of each Tor relay you control, even if they're on 151 | ## different networks. You declare it here so Tor clients can avoid 152 | ## using more than one of your relays in a single circuit. See 153 | ## https://www.torproject.org/docs/faq#MultipleRelays 154 | ## However, you should never include a bridge's fingerprint here, as it would 155 | ## break its concealability and potentially reveal its IP/TCP address. 156 | #MyFamily $keyid,$keyid,... 157 | 158 | ## A comma-separated list of exit policies. They're considered first 159 | ## to last, and the first match wins. If you want to _replace_ 160 | ## the default exit policy, end this with either a reject *:* or an 161 | ## accept *:*. Otherwise, you're _augmenting_ (prepending to) the 162 | ## default exit policy. Leave commented to just use the default, which is 163 | ## described in the man page or at 164 | ## https://www.torproject.org/documentation.html 165 | ## 166 | ## Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses 167 | ## for issues you might encounter if you use the default exit policy. 168 | ## 169 | ## If certain IPs and ports are blocked externally, e.g. by your firewall, 170 | ## you should update your exit policy to reflect this -- otherwise Tor 171 | ## users will be told that those destinations are down. 172 | ## 173 | ## For security, by default Tor rejects connections to private (local) 174 | ## networks, including to your public IP address. See the man page entry 175 | ## for ExitPolicyRejectPrivate if you want to allow "exit enclaving". 176 | ## 177 | #ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more 178 | #ExitPolicy accept *:119 # accept nntp as well as default exit policy 179 | #ExitPolicy reject *:* # no exits allowed 180 | 181 | ## Bridge relays (or "bridges") are Tor relays that aren't listed in the 182 | ## main directory. Since there is no complete public list of them, even an 183 | ## ISP that filters connections to all the known Tor relays probably 184 | ## won't be able to block all the bridges. Also, websites won't treat you 185 | ## differently because they won't know you're running Tor. If you can 186 | ## be a real relay, please do; but if not, be a bridge! 187 | #BridgeRelay 1 188 | ## By default, Tor will advertise your bridge to users through various 189 | ## mechanisms like https://bridges.torproject.org/. If you want to run 190 | ## a private bridge, for example because you'll give out your bridge 191 | ## address manually to your friends, uncomment this line: 192 | #PublishServerDescriptor 0 193 | --------------------------------------------------------------------------------