Running Haskell Servant Behind Tor Hidden Services

Here is the build-depends section:

  build-depends:       base >= 4.7 && < 5,

Here is a minimal example:

{-# LANGUAGE DataKinds     #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeOperators #-}
module Lib
    ( main
    ) where

import           Prelude                  ()
import           Prelude.Compat

import           Control.Concurrent
import           Data.Aeson
import           GHC.Generics
import qualified Network.Anonymous.Tor    as T
import           Network.Socket
import           Network.Wai
import           Network.Wai.Handler.Warp
import           Servant
import           System.IO

data Event = Event {
    id :: Int
  } deriving (Eq, Show, Generic)

instance ToJSON Event

events :: [Event]
events = [
    Event 1,
    Event 2

type API = "events" :> Get '[JSON] [Event]

server :: Server API
server = return events

proxy :: Proxy API
proxy = Proxy

application :: Application
application = serve proxy server

main :: IO ()
main = T.withSession 9151 withinSession
    withinSession :: Socket -> IO ()
    withinSession sock = do
      forkIO $ run 8081 application
      onion <- T.mapOnion sock 80 8081 False Nothing
      print onion
      hWaitForInput stdin (-1)
      putStrLn "Done!"
      return ()

It prints a hidden service address like this:


It quits if you press a key.

You need Tor Browser Bundle running before you run the above code. This is so that the above program connects to Tor and starts an ephemeral hidden service.

After you run the above code, you can access the hidden service after a few minutes (it takes time for hidden service directories to update) by going to http://RANDOMSTRING.onion on your Tor Browser Bundle and you will see this:

Tor Browser_542

It can also work with other Haskell web frameworks. This guy who wrote the library to connect to tor control port has also written similar libraries for I2P connectivity.

Have fun writing web applications that cannot be censored!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s