Avoiding plain-text password in http_proxy

16,536

Solution 1

Using base64 is useless, it's just a simple transformation. Using encryption with a key that's stored alongside the encrypted data is also useless because it's still just a simple transformation. If you're worried about someone getting access to your configuration files, then you need to encrypt with a key that isn't in your configuration files, and that means you'll have to type a password¹ when you log in.

Rather than make your own, use an existing encryption mechanism.

On Linux, if you go with file encryption, encrypt your home directory with eCryptfs, or encrypt the whole disk with Linux's disk encryption layer (dm-crypt, cryptsetup command), or create a small per-file encrypted filesystem with encfs. In the latter case, have a script that mounts the encfs filesystem and then runs a script stored there.

On Windows, put the file on a TrueCrypt/VeraCrypt.

Alternatively, use a password manager (set a master password, of course). Gnome's password manager (gnome-keyring) can be queried from the command line with the secret-tool utility. Seahorse provides a convenient GUI for exploring and modifying the keyring and setting a master password.

secret-tool store --label='Corporate web proxy password' purpose http_proxy location work.example.com

export http_proxy="http://cman:$(secret-tool lookup purpose http_proxy location work.example.com)@192.0.2.3/"

This required D-Bus, which is normally available by default under Linux (most modern desktop environments require it) but needs to be started manually under Cygwin (I don't know exactly how).

¹ or otherwise supply secret material, e.g. stored on a smartcard.

Solution 2

I've found a solution: adding openssl enc -aes-128-cbc -a -d to the mix. However, as mentioned in the accepted answer, this option is probably not very secure.

First, put the username password combo (or base64 encoded equivalent) into here,

echo "<put it here>" | openssl enc -aes-128-cbc -a

It will prompt for a password twice. This password is the password you'll have to input each time http_proxy is set.

Then, in .babunrc (or whereever you put it),

export http_proxy="http://`echo "<output from above command>" | openssl enc -aes-128-cbc -a -d`@20.20.20.20:20/"

If the input was base64 encoded, you'll need this instead:

export http_proxy="http://`echo "<output from above command>" | openssl enc -aes-128-cbc -a -d | base64 -d`@20.20.20.20:20/"

If the <output from above command> had a new line, \n will work for it.

Share:
16,536

Related videos on Youtube

Captain Man
Author by

Captain Man

Updated on September 18, 2022

Comments

  • Captain Man
    Captain Man over 1 year

    I am behind a corporate firewall, which brings lots of pains in the area of proxies. There are two main approaches I've found to work:

    1. Use Cntlm at the cost of not being able to connect (from the command line) to HTTPS and external SSH locations. (Cntlm allows you to hash your username and password using PassNTLMv2 (thus avoiding plain text) and set http://localhost:3128/ as your proxy which then redirects to your "real" proxy. As I mentioned, I cannot connect to HTTPS and external SSH using this method.)
    2. Put my username and password in plain text in the http_proxy variable at the cost of having my username and password in plain text.

    Clearly, if security was not a concern, I'd just do with option 2.

    I found somewhat of a solution, in doing this in my .babrunrc (I use Babun, it's basically Cygwin with a little extra, the same could be in a .bashrc or .zshrc though)

    export http_proxy="http://`echo "Y21hbjpwYXNzd29yZA==" | base64 -d`@20.20.20.20:20/"
    

    This way my password is at least encoded. If someone came to my computer and typed echo $http_proxy they'd see my password, but I don't think there's any way around this.

    Are there any alternative approaches to this? Or maybe a way to encrypt the string as opposed to encoding it? I wouldn't mind typing in some password when I open a prompt if there was no way around it.

    • Admin
      Admin about 8 years
      Why don't you use PASSLM, PASSNT, PASSNTLMv2 from in /etc/cntlm.conf and listen to 3128 port? and export http_proxy/https_proxy to localhost:3128
    • Admin
      Admin about 8 years
      @Thushi this is what I meant by using Cntlm. The problem is that when using Cntlm I cannot connect to HTTPS or external SSH. For example, when Maven tries to grab something from an HTTPS repository it fails. I've looked into this and I am not sure if it's something about the proxy or simply out of scope of Cntlm. There is port redirection (tunneling?) which I believe would work for HTTPS but I don't want to have to make an entry for every single HTTPS link I need to hit, I'd rather have an approach that requires no extra input. I'll modify to make it clear I've tried you're suggestion.
  • Captain Man
    Captain Man about 8 years
    Does openssl enc -aes-128-cbc -a store the key alongside the encrypted data like you said?
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' about 8 years
    @CaptainMan No, but the key is derived from the password in a way that's too easy to brute-force. Like password hashing, password-based key derivation should be salted and slow, but openssl enc isn't slow. Generally speaking, the openssl is horrible and you shouldn't use it unless you know exactly what you're doing (and often not even then): it won't give you any clue whether what you're doing is secure or not.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' about 8 years
    @CaptainMan Oh, sorry, I'd completely missed that you were using Cygwin. I think you can use Gnome-keyring under Cygwin, you'll have to launch D-Bus manually (dbus-launch, maybe set the DBUS_SESSION_BUS_ADDRESS environment variables), but I've never done it so there might be some difficulty I'm not aware of. Encfs and ecryptfs are not an option at all, but you could use a Truecrypt/Veracrypt container.
  • Mashimom
    Mashimom about 6 years
    Would there be a way to add it to the keyring?
  • Captain Man
    Captain Man over 4 years
    @Mashimom Yes, Gilles's answer suggests this approach.
  • Admin
    Admin almost 2 years
    This is a partial solution, no? In the end, your environment will still contain your username and password as plain text, so simply issuing env would expose them.
  • Admin
    Admin almost 2 years
    @TonvandenHeuvel No, using this your environment will have an encrypted version of your username and password. Why do you think it will be unencrypted? If the wording is unclear I can try to improve the answer. (But I suggest you don't use this approach since it's still pretty insecure.)
  • Admin
    Admin almost 2 years
    Ah yes, I missed the base64 encoding...indeed, still pretty insecure. In the end I went with wrapper scripts around processes that require proxy authentication. It still allows inspection of the proxy password by checking the environment of running processes through /proc, but it is the best I could come up with.