diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+0.1.0.25
+--------
+* Add `forbidden-ip` option, which defaults to `127.0.0.1`, to prevent misuse
+  of remote. This is again a feature ported from shadowsocks.
+
 0.1.0.24
 --------
 * Make obfuscation flush upper bound configurable in `config.json`
diff --git a/moesocks.cabal b/moesocks.cabal
--- a/moesocks.cabal
+++ b/moesocks.cabal
@@ -1,6 +1,6 @@
 name:               moesocks
 category:           Network
-version:            0.1.0.24
+version:            0.1.0.25
 license:            Apache-2.0
 synopsis:           A functional firewall killer
 description:        A socks5 proxy using the client / server architecture.
diff --git a/src/Network/MoeSocks/Config.hs b/src/Network/MoeSocks/Config.hs
--- a/src/Network/MoeSocks/Config.hs
+++ b/src/Network/MoeSocks/Config.hs
@@ -32,5 +32,6 @@
   , _forwardUDP = []
   , _disableSocks5 = False
   , _obfuscation = False
+  , _forbidden_IP = ["127.0.0.1"]
   , _params = []
   } 
diff --git a/src/Network/MoeSocks/Options.hs b/src/Network/MoeSocks/Options.hs
--- a/src/Network/MoeSocks/Options.hs
+++ b/src/Network/MoeSocks/Options.hs
@@ -7,6 +7,7 @@
 import Data.Aeson
 import Data.Maybe
 import Data.Text (Text)
+import qualified Data.Text as T
 import Network.MoeSocks.Helper
 import Network.MoeSocks.Type
 import Network.MoeSocks.Config
@@ -184,12 +185,23 @@
       forwardListParser = many' forwardParser
 
       parseForwarding :: Maybe Text -> [Forward]
-      parseForwarding Nothing = []
-      parseForwarding (Just x ) = 
-        x 
+      parseForwarding x = x ^. _Just
           & parseOnly forwardListParser 
           & toListOf (traverse . traverse)
 
+      _forbidden_IP :: O.Parser (Maybe Text)
+      _forbidden_IP = optional - textOption -
+                          long "forbidden-ip"
+                      <>  metavar "IPLIST"
+                      <>  help (""
+                                <> "comma seperated IP list forbidden to "
+                                <> "connect"
+                                )
+     
+      parseForbidden_IP :: Maybe Text -> [Text]
+      parseForbidden_IP = maybe (defaultMoeOptions ^. forbidden_IP) 
+                                (map T.strip . T.splitOn ",")
+
       tag :: a -> O.Parser (Maybe b) -> O.Parser (Maybe (a, b))
       tag x = fmap . fmap - ((,) x)
 
@@ -219,6 +231,7 @@
               <*> fmap parseForwarding _forwardUDP
               <*> _disableSocks5
               <*> _obfuscation
+              <*> fmap parseForbidden_IP _forbidden_IP
               <*> _params
 
 opts :: ParserInfo MoeOptions
diff --git a/src/Network/MoeSocks/TCP.hs b/src/Network/MoeSocks/TCP.hs
--- a/src/Network/MoeSocks/TCP.hs
+++ b/src/Network/MoeSocks/TCP.hs
@@ -187,6 +187,7 @@
         _obfuscation = aEnv ^. options . obfuscation
         _cipherBox = aEnv ^. cipherBox
         _c = aEnv ^. config
+        _options = aEnv ^. options
         _flushBound = _c ^. obfuscationFlushBound
 
   _decodeIV <- recv aSocket (_cipherBox ^. ivLength)
@@ -203,92 +204,98 @@
 
   {-puts - "Remote get: " <> show _clientRequest-}
   
-  logSA "R target socket" (initTarget _clientRequest) - \_r -> do
-    let (_targetSocket, _targetSocketAddress) = _r 
 
-    connect _targetSocket _targetSocketAddress
+  let _requestAddr = showAddressType - _clientRequest ^. addressType
+  if (_requestAddr `elem` (_options ^. forbidden_IP))
+    then pute - show _requestAddr <> " is in forbidden-ip list"
+    else 
+    logSA "R target socket" (initTarget _clientRequest) - \_r -> do
+      let (_targetSocket, _targetSocketAddress) = _r 
 
-    _remotePeerAddr <- getPeerName aSocket
-    _targetPeerAddr <- getPeerName _targetSocket
+      connect _targetSocket _targetSocketAddress
 
-    let _msg = show _remotePeerAddr <> " -> " <> showRequest _clientRequest
+      _remotePeerAddr <- getPeerName aSocket
+      _targetPeerAddr <- getPeerName _targetSocket
 
-    _log - "R T: " <> _msg
+      let _msg = show _remotePeerAddr <> " -> " <> showRequest _clientRequest
 
-    let 
-        handleTarget _leftOverBytes __targetSocket = do
-          _sendChannel <- newTBQueueIO - _c ^. tcpBufferSize
-          _receiveChannel <- newTBQueueIO - _c ^. tcpBufferSize
+      _log - "R T: " <> _msg
 
-          let _logId x = x <> " " <> _msg
-              -- let remote wait slightly longer, so local can timeout
-              -- and disconnect
-              _timeout = (_c ^. timeout + 30) * 1000 * 1000
-              
-              _throttle = 
-                if _c ^. throttle
-                  then Just - _c ^. throttleSpeed
-                  else Nothing
+      let 
+          handleTarget _leftOverBytes __targetSocket = do
+            _sendChannel <- newTBQueueIO - _c ^. tcpBufferSize
+            _receiveChannel <- newTBQueueIO - _c ^. tcpBufferSize
 
-          let sendThread = do
-                when (_leftOverBytes & isn't _Empty) -
-                  atomically - writeTBQueue _sendChannel - S.Just _leftOverBytes
+            let _logId x = x <> " " <> _msg
+                -- let remote wait slightly longer, so local can timeout
+                -- and disconnect
+                _timeout = (_c ^. timeout + 30) * 1000 * 1000
+                
+                _throttle = 
+                  if _c ^. throttle
+                    then Just - _c ^. throttleSpeed
+                    else Nothing
 
-                let _produce = do
-                                  produceLoop (_logId "R --> + Loop")
+            let sendThread = do
+                  when (_leftOverBytes & isn't _Empty) -
+                    atomically - writeTBQueue _sendChannel - 
+                                  S.Just _leftOverBytes
+
+                  let _produce = do
+                                    produceLoop (_logId "R --> + Loop")
+                                      _timeout
+                                      _NoThrottle 
+                                      aSocket
+                                      _sendChannel
+                                      _decrypt
+
+                  let _consume = consumeLoop (_logId "R --> - Loop")
                                     _timeout
-                                    _NoThrottle 
-                                    aSocket
+                                    _NoThrottle
+                                    _targetSocket
                                     _sendChannel
-                                    _decrypt
-
-                let _consume = consumeLoop (_logId "R --> - Loop")
-                                  _timeout
-                                  _NoThrottle
-                                  _targetSocket
-                                  _sendChannel
-                                  False
-                                  _flushBound
+                                    False
+                                    _flushBound
 
-                finally
-                  (
-                    connectMarket (Just - _logId "R --> +", _produce)
-                                  (Just - _logId "R --> -", _consume)
-                  ) -
-                  pure ()
+                  finally
+                    (
+                      connectMarket (Just - _logId "R --> +", _produce)
+                                    (Just - _logId "R --> -", _consume)
+                    ) -
+                    pure ()
 
-          let receiveThread = do
-                _encodeIV <- _cipherBox ^. generateIV 
-                _encrypt <- _cipherBox ^. encryptBuilder - _encodeIV
-                sendBytes _receiveChannel _encodeIV
+            let receiveThread = do
+                  _encodeIV <- _cipherBox ^. generateIV 
+                  _encrypt <- _cipherBox ^. encryptBuilder - _encodeIV
+                  sendBytes _receiveChannel _encodeIV
 
-                let _produce = do
-                                  produceLoop (_logId "R <-- + Loop")
-                                    _timeout
-                                    _NoThrottle 
-                                    _targetSocket
-                                    _receiveChannel
-                                    _encrypt
+                  let _produce = do
+                                    produceLoop (_logId "R <-- + Loop")
+                                      _timeout
+                                      _NoThrottle 
+                                      _targetSocket
+                                      _receiveChannel
+                                      _encrypt
 
 
-                let _consume = do
-                                  consumeLoop (_logId "R <-- - Loop")
-                                    _timeout
-                                    _throttle
-                                    aSocket
-                                    _receiveChannel
-                                    _obfuscation
-                                    _flushBound
+                  let _consume = do
+                                    consumeLoop (_logId "R <-- - Loop")
+                                      _timeout
+                                      _throttle
+                                      aSocket
+                                      _receiveChannel
+                                      _obfuscation
+                                      _flushBound
 
-                finally 
-                  (
-                    connectMarket (Just - _logId "R <-- +", _produce)
-                                  (Just - _logId "R <-- -", _consume)
-                  ) -
-                  pure ()
+                  finally 
+                    (
+                      connectMarket (Just - _logId "R <-- +", _produce)
+                                    (Just - _logId "R <-- -", _consume)
+                    ) -
+                    pure ()
 
-          connectTunnel
-            (Just - _logId "R -->", sendThread)
-            (Just - _logId "R <--", receiveThread)
-          
-    handleTarget _leftOverBytes _targetSocket
+            connectTunnel
+              (Just - _logId "R -->", sendThread)
+              (Just - _logId "R <--", receiveThread)
+            
+      handleTarget _leftOverBytes _targetSocket
diff --git a/src/Network/MoeSocks/Type.hs b/src/Network/MoeSocks/Type.hs
--- a/src/Network/MoeSocks/Type.hs
+++ b/src/Network/MoeSocks/Type.hs
@@ -94,6 +94,7 @@
   , _forwardUDP :: [Forward]
   , _disableSocks5 :: Bool
   , _obfuscation :: Bool
+  , _forbidden_IP :: [Text]
   , _params :: [(Text, Value)]
   }
   deriving (Show, Eq)
diff --git a/src/Network/MoeSocks/UDP.hs b/src/Network/MoeSocks/UDP.hs
--- a/src/Network/MoeSocks/UDP.hs
+++ b/src/Network/MoeSocks/UDP.hs
@@ -97,6 +97,8 @@
                           -> IO ()
 remote_UDP_RequestHandler aEnv aMessage (aSocket, aSockAddr) = do
   let _cipherBox = aEnv ^. cipherBox
+      _options = aEnv ^. options
+
   let (_decodeIV, _eMsg) = S.splitAt (_cipherBox ^. ivLength) 
                                        aMessage 
 
@@ -108,25 +110,29 @@
   {-puts - "R UDP: " <> show _clientRequest-}
   {-puts - "R UDP: " <> show _decryptedMessage-}
   
-  logSA "R UDP -->:" (initTarget _clientRequest) - \_r -> do
-    let (_clientSocket, _clientAddr) = _r
+  let _requestAddr = showAddressType - _clientRequest ^. addressType
+  if (_requestAddr `elem` (_options ^. forbidden_IP))
+    then pute - show _requestAddr <> " is in forbidden-ip list"
+    else 
+    logSA "R UDP -->:" (initTarget _clientRequest) - \_r -> do
+      let (_clientSocket, _clientAddr) = _r
 
-    {-puts - "R UDP clientSocket: " <> show _r-}
-    
-    let _msg = show aSockAddr <> " -> " <> showRequest _clientRequest
-    _log - "R U: " <> _msg
+      {-puts - "R UDP clientSocket: " <> show _r-}
+      
+      let _msg = show aSockAddr <> " -> " <> showRequest _clientRequest
+      _log - "R U: " <> _msg
 
-    connect _clientSocket _clientAddr
-    
-    send_ _clientSocket _decryptedMessage
+      connect _clientSocket _clientAddr
+      
+      send_ _clientSocket _decryptedMessage
 
-    _r <- buildShadowSocksRequest _clientRequest <$> recv_ _clientSocket
+      _r <- buildShadowSocksRequest _clientRequest <$> recv_ _clientSocket
 
-    {-puts - "R UDP <--: " <> show _r-}
+      {-puts - "R UDP <--: " <> show _r-}
 
-    when (_r & isn't _Empty) - do
-      _encodeIV <- _cipherBox ^. generateIV 
-      _encrypt <- _cipherBox ^. encryptBuilder - _encodeIV
-      
-      _encryptedMessage <- processAll _encrypt _r
-      sendAllTo aSocket (_encodeIV <> _encryptedMessage) aSockAddr
+      when (_r & isn't _Empty) - do
+        _encodeIV <- _cipherBox ^. generateIV 
+        _encrypt <- _cipherBox ^. encryptBuilder - _encodeIV
+        
+        _encryptedMessage <- processAll _encrypt _r
+        sendAllTo aSocket (_encodeIV <> _encryptedMessage) aSockAddr
