Hiding Passwords in Scripts

Sometimes you need to pass a password or even just a string on the command line which you would rather obscure.  For example:

serverControl.sh -u admin -p $MYPASS -c shutdown

Note anything below is not the ideal way of dealing with passwords you should probably use SSH keys if possible instead.

Sometimes you really do not have a better option and this might be your only option.  Still it is a weak solution though to store passwords.  I simplified but you probably don’t want to use obvious variable names or files either.

Very simple base64 encoding:

$ echo "passwd" | base64
cGFzc3dkCg==
$ echo "cGFzc3dkCg==" | base64 --decode
passwd

# Use in script as follow or better use a file to store the string:
MYENCPASS="cGFzc3dkCg==" 
MYPASS=`echo "$MYENCPASS" | base64 --decode`

Using aesutil:

I saw someone mention aesutil on the Internet but it appears like few modern Linux distros comes with aesutil tools though.

# mkrand generates a 15-character random
$ SALT=`mkrand 15` passwd

$ `echo "passwd" | aes -e -b -B -p $SALT`
i/b9pkcpQAPy7BzH2JlqHVoJc2mNTBM=

# Use in script as follow or use a file to store the string:
MYENCPASS="i/b9pkcpQAPy7BzH2JlqHVoJc2mNTBM=" 
MYPASS=`echo "$MYENCPASS" | aes -d -b -p $SALT`

Or maybe openssl is an option:

This is still very lame as you still have to use a password for the opensssl command.   I just named it garbageKey but you are probably better off making it more obscure.

# Test
$ echo 'mySecretPassword' | openssl enc -base64 -e -aes-256-cbc -nosalt  -pass pass:garbageKey
yQA4stTBI8njgNgdmttwjlcFrywQD4XEIgK8HzqEOxI=
$ echo 'yQA4stTBI8njgNgdmttwjlcFrywQD4XEIgK8HzqEOxI=' | openssl enc -base64 -d -aes-256-cbc -nosalt -pass pass:garbageKey
mySecretPassword

# Use a hidden file
$ echo 'mySecretPassword' | openssl enc -base64 -e -aes-256-cbc -nosalt  -pass pass:garbageKey > .hidden.lck 
$ cat .hidden.lck 
yQA4stTBI8njgNgdmttwjlcFrywQD4XEIgK8HzqEOxI=

# In a script
$ MYENCPASS=`cat .hidden.lck | openssl enc -base64 -d -aes-256-cbc -nosalt -pass pass:garbageKey`
$ echo $MYENCPASS
mySecretPassword

As you can see in the last example I used a hidden file also instead of keeping the encryption string in the file.

Display X After User Switch

Sometimes you find yourself having to redirect the X display to a different host but “ssh -X hostname” will not work since you had to switch users. For instance you logged to a host as root and afterwards “su – oracle”.

Example:

$ ssh root@host1.domain.com -X
# echo $DISPLAY
localhost:10.0
# xauth list
host1.domain.com/unix:11  MIT-MAGIC-COOKIE-1  95e4b887f2f6d132897aedbbbe297309
host1.domainom/unix:10  MIT-MAGIC-COOKIE-1  961e9e854127e3c70ff8804a5eb57f7e
# su - oracle
$ xauth add host1.domain.com/unix:10  MIT-MAGIC-COOKIE-1  961e9e854127e3c70ff8804a5eb57f7e
xauth:  creating new authority file /home/oracle/.Xauthority

Then trying xclock or xterm worked for me.  If you still have a problem also try:

$ export DISPLAY=localhost:10.0

Setting up TCP Wrappers and local firewall on a remote host

If you use local firewall rules and tcp wrappers on a remote host where you might get locked out, with no easy way to get logged in again, here is a quick howto on playing it safe. The trick is to setup a couple cron jobs to undo whatever you stuffed up.

I scheduled two 10 minute recurring jobs. Gives you 10 minute windows of configuring/testing before security resets.

Paranoid hint: Make sure you stay logged into the target host with an extra terminal somewhere else as well.

I could also have done /etc/init.d/iptables restart or service iptables restart to reset rules from cron. That would prevent you from having a wide open machine after the flush. But the downside of that is if you save rules that were broken, a restart will load your saved (broken) rules.

Set two cron jobs:

[root@uhz002192 dev]# crontab -l
/10 * * * * cp /root/hosts.deny /etc/hosts.deny
/10 * * * * /sbin/iptables --flush

Tcp wrappers:

I made a copy of /etc/hosts.deny file in /root and then waited for the next cron run to test if the copy is really working as expected.

It looked good after cron ran.

# cat /etc/hosts.deny
#
...
#ALL: ALL

Now uncomment the ALL: ALL line in the real /etc/hosts.deny and start testing /etc/hosts.allow rules.

# more /etc/hosts.allow
...
# Host allowed to SSH
sshd: xx.xx.xx.xx

Test from non allowed and allowed host.

Feb 24 05:32:56 uhz002192 sshd[12346]: pam_unix(sshd:session): session opened for user rrosso by (uid=0)
Feb 24 05:33:43 uhz002192 sshd[12380]: refused connect from host.domain.com (::ffff:xx.xx.xx.xx)

Feb 24 05:34:34 uhz002192 sshd[12386]: Accepted password for rrosso from xx.xx.xx.xx port 37415 ssh2
Feb 24 05:34:34 uhz002192 sshd[12386]: pam_unix(sshd:session): session opened for user rrosso by (uid=0)

Now lets go tune the firewall rules…

List rules:


# iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     icmp --  anywhere             anywhere            icmp any
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:webcache
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:etlservicemgr
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:mysql
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:redwood-broker
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:smtp
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ftp
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:https
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Saved rules in this file:

# cat /etc/sysconfig/iptables
# Firewall configuration written by system-config-securitylevel
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp --icmp-type any -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 9001 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3001 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT

Delete unneeded rules:

# iptables -D INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
# iptables -D INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
# iptables -D INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
# iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT

Check (and test using something like nmap):

# iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     icmp --  anywhere             anywhere            icmp any
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:etlservicemgr
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:redwood-broker
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:https
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Save the rules:

# service iptables save
Saving firewall rules to /etc/sysconfig/iptables:          [  OK  ]

Check stored rules:

# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.3.5 on Fri Feb 24 05:48:21 2012
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [734:96465]
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 9001 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3001 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Fri Feb 24 05:48:21 2012

Check running rules:

# iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     icmp --  anywhere             anywhere            icmp any
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:etlservicemgr
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:redwood-broker
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:https
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Delete the cron job(s) when working!