Site Posts - Embrace the Unknown

Setting up this site for free

In the process of creating this site with an abnormal way (using ddns), most people had told me to give up and go buy a domain, I refuse. And now, here am I.

First they ignore you, then they laugh at you, then they fight you, then you win. -- Mahatma Gandhi

Warning: Always believe in yourselves and never give up during the process.

Patience and diligence, like faith, remove mountains. -- Willian Penn

HTTP Setup

Build website

Clone the [website source][src] in /srv/www/ Run make with the following

#TARG=/srv/http/pickfireywcq2wf2.onion  # build with this as well for tor

Setup httpd

Install h2o.

Base website with virtual host and tor support.

  "": &www
    listen: 80
    paths: &www_paths
        file.dir: /srv/http/
        file.send-compressed: ON
        access-log: /var/log/h2o/www.log
        fastcgi.spawn: "exec /srv/tor/check/check.cgi"
        access-log: /var/log/h2o/tor.log
      /status: &default_status
        mruby.handler: |
          acl {
            allow { addr == "" }
            respond(404, {}, ["not found"])
        status: ON
        access-log: /var/log/h2o/status.log
    <<: *www
      <<: *www_paths
        file.dir: /srv/http/pickfireywcq2wf2.onion
        file.send-compressed: ON
      port: 443
      ssl: &default_ssl
        minimum-version: TLSv1.2
        certificate-file: /srv/www/
        key-file: /srv/www/
    header.set: "Strict-Transport-Security: max-age=15768000; includeSubDomains"
    paths: *www_paths

Use as Let's Encrypt client (minimal client for posix shell).

git clone
./ --install --home /srv/www/

Setup certs:

. /srv/www/ --issue -d -d -w /srv/http/

For cgit (this took me a while to figure it out):

"": &git
  listen: 80
  paths: &git_paths
      file.file: /srv/git/cgit.css
      file.send-compressed: ON
    /favicon.ico: &default_ico
      file.file: /srv/www/
      file.send-compressed: ON
      fastcgi.spawn: "exec $H2O_ROOT/share/h2o/fastcgi-cgi"
        SCRIPT_FILENAME: /srv/git/cgit.cgi
      compress: ON
      access-log: /var/log/h2o/git.log
    /status: *default_status

For files with auto index:

"": &dl
  listen: 80
  paths: &dl_paths
      file.dir: "/srv/ftp"
      file.dirlisting: ON
      compress: ON
      access-log: /var/log/h2o/dl.log
    /favicon.ico: *default_ico
    /status: *default_status

Setup cgit

Install cgit, fcgiwrap (now used the one in h2o).

Setup git daemon

Install git-daemon.

Bare repository

Do git clone --bare for the files.

Owner of git repository is appended to repo/config.

	owner = Ivan Tham <>

Project description in repo/description.

DNS setup

Aha, free sites


Get my domain here

NSD DNS server

I use nsd authoritative-only dns server in conjunction with dnsmasq. (Not applicable anymore after switching to cloudflare DNS)

Zone file

In /etc/nsd/

$TTL 300

; Start of authority (required)
@       IN      SOA (
                2016071701      ; Serial
                300             ; refresh
                300             ; retry
                2W              ; expire
                1D              ; minimum TTL

; Name servers
        IN      NS
        IN      NS
        IN      NS
        IN      NS
;       IN      NS
;       IN      NS
;       IN      NS
;       IN      NS
;       IN      NS

; A records for name servers
;       IN      A
;      IN      A

; Resource records
@       IN      A
www     IN      A

Backup DNS

Cloudflare DNS-only with the following dns update script.

curl -s -X GET "" \
  -H "X-Auth-Email:" \
  -H "Content-Type: application/json" \
  | jq -r ".result[] | select(.type == \"A\") | @sh \"curl -s -w '\n' -X PUT\(.id) -H 'X-Auth-Email:' -H 'X-Auth-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -H 'Content-Type: application/json' -d '\" + ({type: \"A\", name: .name, content: \"$IP\"} | tostring) + \"'\"" \
  | xargs -0 sh -c


Search Arch wiki for the following.

Open DNS

Using this setup, people could just spoof udp request and use the server as a bot to ddos other servers. To solve this fast, I did this myself without my father's help (slow), so I did add an iptables rule. external:53 -> internal:5353

iptables -t nat -A PREROUTING -s -p udp -m udp --dport 53 -j DNAT --to

Dynamic DNS service (old setup)

I personally used after signing up for a few dns service.

Port forwarding

I am not sure about this. Go ask my father.

Tor Hidden Service

Why? Firewall isn't Tor-proof, prevent censorship and support a better privacy.

Setup Tor hidden service

Edit /etc/tor/torrc, private keys in /srv/tor for Alpine data-mode.

DNSPort 9053

HiddenServiceDir /srv/tor/web/
HiddenServicePort 80
HiddenServicePort 9418