Re: Enforce encryption client-side
Nils-Johan Andreasson wrote on Fri, May 07, 2021 at 15:41:47 +0200: > On Thu, May 6, 2021 at 3:24 PM Daniel Shahaf wrote: > > > Nils-Johan Andreasson wrote on Thu, May 06, 2021 at 14:48:01 +0200: > > > I have indeed considered svn+ssh but there are other details involved > > which > > > makes me prefer to stay with svnserve and svn:// if possible. > > > > Does your library consider svn+foo:// secure? If so, you can define an > > svn+foo:// scheme that simply wraps plain old TCP sockets. You have two > > options for that, even: either «svn+nc://hostname/path» that uses nc(1) > > or socat(1) to wrap a plain TCP socket, or a scheme that hardcodes > > a specific hostname, that you then use in URLs whose hostname component is > > ignored (can actually be left empty). > > Clever! > The library does indeed only consider svn:// insecure and it does not > validate the scheme other than that. So, this would work (although it of > course requires some configuration in the places I want to use it, but I > can live with that). > > It took me some reading and fiddling though to get this to work completely. > nc wants parameters as 'nc '. > The command defined in subversion config under [tunnels] is called as: > svnserve -t ⋮ > Which in the end makes a command such as this work like a charm: > svn info svn+nc://hostname:3699 > > Maybe you had a simpler way of achieving the same in mind? No. You _could_ inline the wrapper script into the configuration, along these lines: . [tunnels] nc = $SUBVERSION_TUNNEL_NC sh -c 'nc ${1%:*} ${1##*:}' : . but other than that, what you did is exactly what I had in mind. Sorry it wasn't clear the first time. BTW, to support the default port: . nc = $SUBVERSION_TUNNEL_NC sh -c 'case $1 in *:*) ;; *) set -- ${1}:3690;; esac && nc ${1%:*} ${1##*:}' : I've committed a related clarification in https://svn.apache.org/r1889629. Thanks for raising that. The other approach I described was to define a tunnel such as . [tunnels] bar = $BAR sh -c "nc lorem.bar.example 3690" . which can then be used as «svn+bar:///some/path» with an empty hostname component. I used to do this, for two reasons: it made the URLs shorter, and it let me change the SSH jumphost centrally across all my working copies. > In any case, thanks a lot all for your helpful inputs and suggestions - > made my day! You're welcome. Daniel
Re: Enforce encryption client-side
Clever! The library does indeed only consider svn:// insecure and it does not validate the scheme other than that. So, this would work (although it of course requires some configuration in the places I want to use it, but I can live with that). It took me some reading and fiddling though to get this to work completely. nc wants parameters as 'nc '. The command defined in subversion config under [tunnels] is called as: svnserve -t This will make nc treat "svnserve" as the port and therefore refuse it. Specifying hostname as hostname:port will not work either. For now, I wrote a small bash script "nc-forwarder" with the following contents: #!/bin/bash nc $(echo $1 | sed 's/:/ /g') Made it executable chmod +x nc-forwarder Put it in the config: [tunnels] nc = /home/xx/.subversion/nc-forwarder When run it simply executes nc with the first argument. In my case I use a custom port so it replaces the colon with space which works great with nc. If no custom port is used you can always add :3690 (or enhance the bash script further to set that as default port). All other arguments (svnserve -t) are at the same time scrapped. Which in the end makes a command such as this work like a charm: svn info svn+nc://hostname:3699 Maybe you had a simpler way of achieving the same in mind? In any case, thanks a lot all for your helpful inputs and suggestions - made my day! Best regards, Nils-Johan On Thu, May 6, 2021 at 3:24 PM Daniel Shahaf wrote: > Nils-Johan Andreasson wrote on Thu, May 06, 2021 at 14:48:01 +0200: > > I have indeed considered svn+ssh but there are other details involved > which > > makes me prefer to stay with svnserve and svn:// if possible. > > Does your library consider svn+foo:// secure? If so, you can define an > svn+foo:// scheme that simply wraps plain old TCP sockets. You have two > options for that, even: either «svn+nc://hostname/path» that uses nc(1) > or socat(1) to wrap a plain TCP socket, or a scheme that hardcodes > a specific hostname, that you then use in URLs whose hostname component is > ignored (can actually be left empty). >
Re: Enforce encryption client-side
On Thu, May 06, 2021 at 09:15:44AM -0400, Mark Phippard wrote: > I am not familiar with the SASL options in the client config Neither was I, and after some investigation of the code I concluded that there are none. They're only available in svnserve/libsvn_repos. Client-side support for these options would need to be added in order to satisfy the use case under discussion.
Re: Enforce encryption client-side
Nils-Johan Andreasson wrote on Thu, May 06, 2021 at 13:03:28 +0200: > Thanks Stefan for your response and pointers! > > There is no doubt my connections are already encrypted. > The issue is that the external library I'm referring to supports specifying > paths to source code using multiple protocols, e.g. svn:// (but also > https://, http://, git://, ftp:// etc) and any svn:// source is generally > considered insecure, just like http:// (but not for example https://). It > is not verified in any way if that's actually the case, it's just based on > the scheme prefix svn:// > > Using something like that I can hopefully convince the library maintainer > to enable this flag by default and then consider an svn:// source secure by > default (as connection would otherwise not succeed). You could also point out to the library author that treating svn://foo/ as insecure would be wrong when foo is an IP address on a VPN, or a loopback address, or an address of a virtualized box running on the same hardware, and so on, even if no encryption is used at all. Cheers, Daniel > I understand your point with that as long as "use-sasl = true" is > configured on the server, the connection would abort if the client cannot > communicate securely. However, this means that if this external library is > pointed to a svn:// source with "use-sasl = false" the connection would > succeed, which is what I'm trying to prevent here to guarantee no > unencrypted connections are made. > > Hope my point came through better this time? > > Best regards, > > Nils-Johan > > > On Thu, May 6, 2021 at 11:40 AM Stefan Sperling wrote: > > > On Thu, May 06, 2021 at 11:21:57AM +0200, Nils-Johan Andreasson wrote: > > > Hi there! > > > > > > I'm serving a repository using svnserve with SASL to make sure > > > communication is always encrypted (config has use-sasl = true, > > > min-encryption = 128 and max-encryption = 256). > > > I know this enforces encryption server-side but is there any way to in > > > addition also "require" encryption client-side? E.g. let's say if I do > > 'svn > > > checkout svn://my-insecure-host/repository' I want the command to abort > > if > > > the connection is not encrypted. > > > > The min-encryption paramter maps directly to the Cyrus SASL > > secprops.min_ssf > > paramter which is described here: > > > > https://www.cyrusimap.org/sasl/sasl/developer/programming.html#security-layers > > > > Quote: > > "A connection supplying only integrity with no privacy would have an SSF > > of 1. > > A connection secured by 56-bit DES would have an SSF of 56. > > To require a security layer, set min_ssf to the minimum acceptable security > > layer strength." > > > > SVN servers and clients check the SASL_SSF property of their connection > > here > > and abort if SASL failed to negotiate encryption if encryption is > > configured: > > > > https://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/cyrus_auth.c?revision=1875971=markup#l726 > > > > So your connections should already be encrypted. Perhaps the encryption > > mechanism SASL is using is considered too weak by your external tool? > > Would setting min-encryption = 256 help? > > Or perhaps your external tool simply doesn't understand the SVN protocol? > > > > Cheers, > > Stefan > >
Re: Enforce encryption client-side
Nils-Johan Andreasson wrote on Thu, May 06, 2021 at 14:48:01 +0200: > Is there a way (command) to remotely determine if the svn server behind > 'hostname' has sasl enabled/uses encryption/enforces a min_ssf >= 128? > Preferably without having to send any authentication credentials (to not > risk sending anything in clear text). Possibly. Look into the handshake in subversion/libsvn_ra_svn/protocol, Section 2, specifically the «auth-request» line (the second thing the server sends). You can try it on a toy example like this: % svnadmin create r % ${EDITOR:-ed} r/conf/svnserve.conf % printf '%s\n' '( 2 ( edit-pipeline ) 17:svn://localhost/r )' | svnserve -i -r ./ Or on a real server with something like this: % printf '( 2 ( edit-pipeline ) %d:%s )\n' "$(printf %s "$url" | wc -c)" "$url" | nc $url 3690 When I do that I get "Could not obtain the list of SASL mechanisms" (E170001 SVN_ERR_RA_NOT_AUTHORIZED), but you should get an actual response. Does that response provide the information you seek? > If so, an initialization step could hopefully be added which determines > whether the source is deemed to be secure to access or not.
Re: Enforce encryption client-side
Nils-Johan Andreasson wrote on Thu, May 06, 2021 at 14:48:01 +0200: > I have indeed considered svn+ssh but there are other details involved which > makes me prefer to stay with svnserve and svn:// if possible. Does your library consider svn+foo:// secure? If so, you can define an svn+foo:// scheme that simply wraps plain old TCP sockets. You have two options for that, even: either «svn+nc://hostname/path» that uses nc(1) or socat(1) to wrap a plain TCP socket, or a scheme that hardcodes a specific hostname, that you then use in URLs whose hostname component is ignored (can actually be left empty).
Re: Enforce encryption client-side
On Thu, May 6, 2021 at 8:57 AM Nils-Johan Andreasson wrote: > > Thanks for excellent input! > > Unfortunately this external library is being very widely used and is not > shipped with svn included. Rather it relies on being able to use svn if > detected as installed on the system, so simply waiting for a new release > wouldn't be an option to make a library-wide change. > > The only other work-around I can come to think of would be if there is a way > to probe whether a server uses/requires encryption for communication. > Let's say I access svn://hostname/repository > Is there a way (command) to remotely determine if the svn server behind > 'hostname' has sasl enabled/uses encryption/enforces a min_ssf >= 128? > Preferably without having to send any authentication credentials (to not risk > sending anything in clear text). > If so, an initialization step could hopefully be added which determines > whether the source is deemed to be secure to access or not. > > I have indeed considered svn+ssh but there are other details involved which > makes me prefer to stay with svnserve and svn:// if possible. All commands already accept the --config-option, so you could just cherry pick something from your existing client configuration that you pass on the command line and then ask your library to look for the presence of that option(s) as a sign that the connection is encrypted. I am not familiar with the SASL options in the client config, but this is an example from the documentation: --config-option servers:global:http-library=serf So any value from the servers or config file can be passed on the command line. Hope this helps Mark
Re: Enforce encryption client-side
Thanks for excellent input! Unfortunately this external library is being very widely used and is not shipped with svn included. Rather it relies on being able to use svn if detected as installed on the system, so simply waiting for a new release wouldn't be an option to make a library-wide change. The only other work-around I can come to think of would be if there is a way to probe whether a server uses/requires encryption for communication. Let's say I access svn://hostname/repository Is there a way (command) to remotely determine if the svn server behind 'hostname' has sasl enabled/uses encryption/enforces a min_ssf >= 128? Preferably without having to send any authentication credentials (to not risk sending anything in clear text). If so, an initialization step could hopefully be added which determines whether the source is deemed to be secure to access or not. I have indeed considered svn+ssh but there are other details involved which makes me prefer to stay with svnserve and svn:// if possible. Best regards, Nils-Johan On Thu, May 6, 2021 at 1:52 PM Stefan Sperling wrote: > On Thu, May 06, 2021 at 01:03:28PM +0200, Nils-Johan Andreasson wrote: > > Thanks Stefan for your response and pointers! > > > > There is no doubt my connections are already encrypted. > > The issue is that the external library I'm referring to supports > specifying > > paths to source code using multiple protocols, e.g. svn:// (but also > > https://, http://, git://, ftp:// etc) and any svn:// source is > generally > > considered insecure, just like http:// (but not for example https://). > It > > is not verified in any way if that's actually the case, it's just based > on > > the scheme prefix svn:// > > > > So, what I'm looking for is a way to ensure an svn client command is only > > allowed to execute if using an encrypted transport. E.g. something like: > > svn --enforce-encryption checkout svn://hostname/repository > > svn --min-encryption 128 checkout svn://hostname/repository > > (or --disallow-unencrypted-transport, --require-sasl etc) > > > > Using something like that I can hopefully convince the library maintainer > > to enable this flag by default and then consider an svn:// source secure > by > > default (as connection would otherwise not succeed). > > > > I understand your point with that as long as "use-sasl = true" is > > configured on the server, the connection would abort if the client cannot > > communicate securely. However, this means that if this external library > is > > pointed to a svn:// source with "use-sasl = false" the connection would > > succeed, which is what I'm trying to prevent here to guarantee no > > unencrypted connections are made. > > > > Hope my point came through better this time? > > Yes. It seems indeed impossible to enforce a min_sff parameter other than > zero on the client side at present, which is an unfortunate omission. > I am sure there is no technical reason which would prevent this from > becoming configurable. > > If you or the third-party library maintainer are compiling your own > client binaries, the easy way to fix this would be to set min_ssf here: > > https://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/cyrus_auth.c?view=markup#l276 > > When adding this an official Subversion feature, I would suggest to > expose the SASL configuration parameters that svnserve is already using > as part of the client-side configuration, and then ensuring that these > parameters are applied after svn_ra_svn__default_secprops() is called. > Note that any configuration file parameters can also be specified on > the command line via the --config-option option so you won't necessarily > need to add a new separate option to the command line interface if this > feature gets implemented via config file options. > > I agree that this would be useful. However, someone would need to write > a patch, and then you would have to wait for a Subversion 1.15 release > to ship since this feature cannot be added in a 1.14 patch release due > to our compatibility promises (a clean roll-back from 1.14.Y to 1.14.X > without any configuration/parameter changes must remain possible). And > your third party library would need to upgrade to that version once it > has been released. All of this could take many months. > > Have you considered using svn+ssh instead? > > Cheers, > Stefan >
Re: Enforce encryption client-side
On Thu, May 06, 2021 at 01:03:28PM +0200, Nils-Johan Andreasson wrote: > Thanks Stefan for your response and pointers! > > There is no doubt my connections are already encrypted. > The issue is that the external library I'm referring to supports specifying > paths to source code using multiple protocols, e.g. svn:// (but also > https://, http://, git://, ftp:// etc) and any svn:// source is generally > considered insecure, just like http:// (but not for example https://). It > is not verified in any way if that's actually the case, it's just based on > the scheme prefix svn:// > > So, what I'm looking for is a way to ensure an svn client command is only > allowed to execute if using an encrypted transport. E.g. something like: > svn --enforce-encryption checkout svn://hostname/repository > svn --min-encryption 128 checkout svn://hostname/repository > (or --disallow-unencrypted-transport, --require-sasl etc) > > Using something like that I can hopefully convince the library maintainer > to enable this flag by default and then consider an svn:// source secure by > default (as connection would otherwise not succeed). > > I understand your point with that as long as "use-sasl = true" is > configured on the server, the connection would abort if the client cannot > communicate securely. However, this means that if this external library is > pointed to a svn:// source with "use-sasl = false" the connection would > succeed, which is what I'm trying to prevent here to guarantee no > unencrypted connections are made. > > Hope my point came through better this time? Yes. It seems indeed impossible to enforce a min_sff parameter other than zero on the client side at present, which is an unfortunate omission. I am sure there is no technical reason which would prevent this from becoming configurable. If you or the third-party library maintainer are compiling your own client binaries, the easy way to fix this would be to set min_ssf here: https://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/cyrus_auth.c?view=markup#l276 When adding this an official Subversion feature, I would suggest to expose the SASL configuration parameters that svnserve is already using as part of the client-side configuration, and then ensuring that these parameters are applied after svn_ra_svn__default_secprops() is called. Note that any configuration file parameters can also be specified on the command line via the --config-option option so you won't necessarily need to add a new separate option to the command line interface if this feature gets implemented via config file options. I agree that this would be useful. However, someone would need to write a patch, and then you would have to wait for a Subversion 1.15 release to ship since this feature cannot be added in a 1.14 patch release due to our compatibility promises (a clean roll-back from 1.14.Y to 1.14.X without any configuration/parameter changes must remain possible). And your third party library would need to upgrade to that version once it has been released. All of this could take many months. Have you considered using svn+ssh instead? Cheers, Stefan
Re: Enforce encryption client-side
Thanks Stefan for your response and pointers! There is no doubt my connections are already encrypted. The issue is that the external library I'm referring to supports specifying paths to source code using multiple protocols, e.g. svn:// (but also https://, http://, git://, ftp:// etc) and any svn:// source is generally considered insecure, just like http:// (but not for example https://). It is not verified in any way if that's actually the case, it's just based on the scheme prefix svn:// So, what I'm looking for is a way to ensure an svn client command is only allowed to execute if using an encrypted transport. E.g. something like: svn --enforce-encryption checkout svn://hostname/repository svn --min-encryption 128 checkout svn://hostname/repository (or --disallow-unencrypted-transport, --require-sasl etc) Using something like that I can hopefully convince the library maintainer to enable this flag by default and then consider an svn:// source secure by default (as connection would otherwise not succeed). I understand your point with that as long as "use-sasl = true" is configured on the server, the connection would abort if the client cannot communicate securely. However, this means that if this external library is pointed to a svn:// source with "use-sasl = false" the connection would succeed, which is what I'm trying to prevent here to guarantee no unencrypted connections are made. Hope my point came through better this time? Best regards, Nils-Johan On Thu, May 6, 2021 at 11:40 AM Stefan Sperling wrote: > On Thu, May 06, 2021 at 11:21:57AM +0200, Nils-Johan Andreasson wrote: > > Hi there! > > > > I'm serving a repository using svnserve with SASL to make sure > > communication is always encrypted (config has use-sasl = true, > > min-encryption = 128 and max-encryption = 256). > > I know this enforces encryption server-side but is there any way to in > > addition also "require" encryption client-side? E.g. let's say if I do > 'svn > > checkout svn://my-insecure-host/repository' I want the command to abort > if > > the connection is not encrypted. > > The min-encryption paramter maps directly to the Cyrus SASL > secprops.min_ssf > paramter which is described here: > > https://www.cyrusimap.org/sasl/sasl/developer/programming.html#security-layers > > Quote: > "A connection supplying only integrity with no privacy would have an SSF > of 1. > A connection secured by 56-bit DES would have an SSF of 56. > To require a security layer, set min_ssf to the minimum acceptable security > layer strength." > > SVN servers and clients check the SASL_SSF property of their connection > here > and abort if SASL failed to negotiate encryption if encryption is > configured: > > https://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/cyrus_auth.c?revision=1875971=markup#l726 > > So your connections should already be encrypted. Perhaps the encryption > mechanism SASL is using is considered too weak by your external tool? > Would setting min-encryption = 256 help? > Or perhaps your external tool simply doesn't understand the SVN protocol? > > Cheers, > Stefan >
Re: Enforce encryption client-side
On Thu, May 06, 2021 at 11:21:57AM +0200, Nils-Johan Andreasson wrote: > Hi there! > > I'm serving a repository using svnserve with SASL to make sure > communication is always encrypted (config has use-sasl = true, > min-encryption = 128 and max-encryption = 256). > I know this enforces encryption server-side but is there any way to in > addition also "require" encryption client-side? E.g. let's say if I do 'svn > checkout svn://my-insecure-host/repository' I want the command to abort if > the connection is not encrypted. The min-encryption paramter maps directly to the Cyrus SASL secprops.min_ssf paramter which is described here: https://www.cyrusimap.org/sasl/sasl/developer/programming.html#security-layers Quote: "A connection supplying only integrity with no privacy would have an SSF of 1. A connection secured by 56-bit DES would have an SSF of 56. To require a security layer, set min_ssf to the minimum acceptable security layer strength." SVN servers and clients check the SASL_SSF property of their connection here and abort if SASL failed to negotiate encryption if encryption is configured: https://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/cyrus_auth.c?revision=1875971=markup#l726 So your connections should already be encrypted. Perhaps the encryption mechanism SASL is using is considered too weak by your external tool? Would setting min-encryption = 256 help? Or perhaps your external tool simply doesn't understand the SVN protocol? Cheers, Stefan
Enforce encryption client-side
Hi there! I'm serving a repository using svnserve with SASL to make sure communication is always encrypted (config has use-sasl = true, min-encryption = 128 and max-encryption = 256). I know this enforces encryption server-side but is there any way to in addition also "require" encryption client-side? E.g. let's say if I do 'svn checkout svn://my-insecure-host/repository' I want the command to abort if the connection is not encrypted. The background to this question is that I'm using an external library which sees all usage of svn:// protocol as insecure. In our case, it doesn't make sense since we have encryption configured but to be able to use svn:// URLs I need to configure this library to allow "insecure connections" which affects a lot of other things and also creates warnings, unnecessarily. My idea would be to suggest the library maintainer to let me configure an additional parameter/config to supply to the svn binary to make sure connection is only allowed if encrypted, e.g. 'svn --enforce-encryption checkout svn://my-insecure-url/repository'. By that, the library could trust connections to always be encrypted for a specific svn:// URL instead of having to turn on a more library-wide "always allow unencrypted connections" which is generally a bad idea. Any ideas if this is achievable? Thanks in advance! Best regards, NJ