annex.security.allowed-ip-addresses ports syntax

Extended annex.security.allowed-ip-addresses to let specific ports of an IP
address to be used, while denying use of other ports.
This commit is contained in:
Joey Hess 2020-02-25 15:45:52 -04:00
parent 4316d92b48
commit 9659f1c30f
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
6 changed files with 43 additions and 7 deletions

View file

@ -41,6 +41,7 @@ import qualified BuildInfo
import Network.Socket
import Network.HTTP.Client
import Network.HTTP.Client.TLS
import Text.Read
defaultUserAgent :: U.UserAgent
defaultUserAgent = "git-annex/" ++ BuildInfo.packageversion
@ -85,10 +86,11 @@ getUrlOptions = Annex.getState Annex.urloptions >>= \case
manager <- liftIO $ U.newManager $
avoidtimeout $ tlsManagerSettings
return (urldownloader, manager)
allowedaddrs -> do
allowedaddrsports -> do
addrmatcher <- liftIO $
(\l v -> any (\f -> f v) l) . catMaybes
<$> mapM makeAddressMatcher allowedaddrs
<$> mapM (uncurry makeAddressMatcher)
(mapMaybe splitAddrPort allowedaddrsports)
-- Default to not allowing access to loopback
-- and private IP addresses to avoid data
-- leakage.
@ -120,6 +122,19 @@ getUrlOptions = Annex.getState Annex.urloptions >>= \case
-- separate timeout controls, so disable that.
avoidtimeout s = s { managerResponseTimeout = responseTimeoutNone }
splitAddrPort :: String -> Maybe (String, Maybe PortNumber)
splitAddrPort s
-- "[addr]:port" (also allow "[addr]")
| "[" `isPrefixOf` s = case splitc ']' (drop 1 s) of
[a,cp] -> case splitc ':' cp of
["",p] -> do
pn <- readMaybe p
return (a, Just pn)
[""] -> Just (a, Nothing)
_ -> Nothing
_ -> Nothing
| otherwise = Just (s, Nothing)
ipAddressesUnlimited :: Annex Bool
ipAddressesUnlimited =
("all" == ) . annexAllowedIPAddresses <$> Annex.getGitConfig

View file

@ -32,6 +32,8 @@ git-annex (8.20200221) UNRELEASED; urgency=medium
* init --version: When the version given is one that automatically
upgrades to a newer version, use the newer version instead.
* Auto upgrades from older repo versions, like v5, now jump right to v8.
* Extended annex.security.allowed-ip-addresses to let specific ports
of an IP address to be used, while denying use of other ports.
-- Joey Hess <id@joeyh.name> Wed, 19 Feb 2020 12:48:58 -0400

View file

@ -103,10 +103,12 @@ embeddedIpv4 v = case v of
- match that address in a SockAddr. Nothing when the address cannot be
- parsed.
-
- When a port is specified, will only match a SockAddr using the same port.
-
- This does not involve any DNS lookups.
-}
makeAddressMatcher :: String -> IO (Maybe (SockAddr -> Bool))
makeAddressMatcher s = go
makeAddressMatcher :: String -> Maybe PortNumber -> IO (Maybe (SockAddr -> Bool))
makeAddressMatcher s mp = go
<$> catchDefaultIO [] (getAddrInfo (Just hints) (Just s) Nothing)
where
hints = defaultHints
@ -117,6 +119,11 @@ makeAddressMatcher s = go
go [] = Nothing
go l = Just $ \sockaddr -> any (match sockaddr) (map addrAddress l)
match (SockAddrInet _ a) (SockAddrInet _ b) = a == b
match (SockAddrInet6 _ _ a _) (SockAddrInet6 _ _ b _) = a == b
match (SockAddrInet p a) (SockAddrInet _ b) = a == b && matchport p
match (SockAddrInet6 p _ a _) (SockAddrInet6 _ _ b _) = a == b && matchport p
match _ _ = False
matchport p = case mp of
Nothing -> True
Just p' -> p == p'

View file

@ -1608,6 +1608,11 @@ Remotes are configured using these settings in `.git/config`.
Note that, since the interfaces of curl and youtube-dl do not allow
these IP address restrictions to be enforced, curl and youtube-dl will
never be used unless annex.security.allowed-ip-addresses=all.
To allow accessing local or private IP addresses on only specific ports,
use the syntax "[addr]:port". For example,
"[127.0.0.1]:80 [127.0.0.1]:443 [::1]:80 [::1]:443" allows
localhost on the http ports only.
* `annex.security.allowed-http-addresses`

View file

@ -4,7 +4,7 @@
date="2020-02-25T18:32:02Z"
content="""
As to ports, it seems reasonable to support eg
security.allowed-ip-addresses=127.0.0.1:80 to make sure that the massive
security.allowed-ip-addresses=[127.0.0.1]:80 to make sure that the massive
electron app I have running on some random other port doesn't get abused
to exfiltrate the contents of my $HOME. As a non-random example. :)
"""]]

View file

@ -0,0 +1,7 @@
[[!comment format=mdwn
username="joey"
subject="""comment 3"""
date="2020-02-25T19:30:35Z"
content="""
Implemented specifying allowed ports.
"""]]