summaryrefslogtreecommitdiff
path: root/articles/pam-tfa.html
blob: 7bdc551217b585b5f9f187fb395a0dacba363d71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<!DOCTYPE html>
<html lang=en>
    <head>
        <title></title>
        <meta charset="utf-8"/>
        <link rel="shortcut icon" href="favicon.ico"/>
        <link rel='stylesheet' href='../style.css'/>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
<body>
    <header><h1>PAM OATH Two Factor Authentication</h1></header>
    <main>
			<p>In this article we are going to look at configuring two factor 
			authentication via PAM using OATH. This is a simple and private way 
			to increase the security of your systems. Even if you are not familiar 
			with the term, it is likely that you 
			have used OATH before. OATH (specifically TOTP) is the rotating 6 
			digit code that you get from scanning a QR code when setting up 2FA 
			on an account.</p>

			<p>This example will show how to configure 2FA for SSH logins to a 
			server, but can easily be generalized to cover other programs or 
			even all authentication on a system. The two factors here will be 
			public key authentication and then the OATH/TOTP code. 
			<em>It is highly recommended that you remain SSHd into your server 
			until after testing to avoid locking yourself out in the event 
			of a configuration error.</em></p>

			<h2>Install Packages</h2>
			<p>You only need to install a single package on the server side.</p>

			<pre><code>apt install libpam-oath</code></pre>

			<p>On the client machine that will be SSHing to the server install 
			these two packages.</p>

			<pre><code>apt install oathtool qrencode</code></pre>

			<h2>Configure OATH</h2>
			<p>Create the OATH configuration file <strong>/etc/users.oath</strong>. 
			This file will contain the OATH secret keys so permissions need to be 
			set to only allow the root user to view it.</p>

			<pre><code>touch /etc/users.oath
chown root: /etc/users.oath
chmod 600 /etc/users.oath</code></pre>

			<p>Generate a secret key for the TOTP. Treat this secret key as you 
			would your SSH or GPG private key. Anyone who has this key will be able 
			to generate the code needed to authenticate.</p>

			<pre><code>openssl rand -hex 10</code></pre>

			<p>Now we define the TOTP configuration for our user. If you were 
			setting this up for multiple users you would make one entry per line. 
			Open <strong>/etc/users.oath</strong> and add this line. 
			<em>user</em> is the username of the account you will SSH into. 
			Replace the long string of numbers and letters with the secret key 
			you just generated.</p>

			<pre><code>HOTP/T30/6 <em>user</em> - <em>00112233445566aabbcc</em></code></pre>


			<h2>Configure PAM</h2>
			<p>Now we need to tell PAM to use OATH to authenticate sshd. Do that 
			by opening <strong>/etc/pam.d/sshd</strong> and adding the following 
			line to the top of the file.</p>

			<pre><code>auth sufficient pam_oath.so usersfile=/etc/users.oath window=30 digits=6</code></pre>

			<p>This tells PAM to consider a valid 6 digit code as fully authenticated 
			and to skip any other processing that may normally occur, such as 
			requesting a password.</p>

			<h2>Configure SSHD</h2>
			<p>We need to make a few changes to the sshd configuration to allow 
			OATH to work properly. Open the sshd configuration file at 
			<strong>/etc/ssh/sshd_config</strong> and make the following changes.</p>

			<pre><code>AuthenticationMethods publickey,keyboard-interactive
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
UsePAM yes</code></pre>

			<p>The <strong>AuthenticationMethods</strong> line specifically tells 
			sshd that a user needs to both have an authorized SSH key and know 
			the proper 6 digit code to login.</p>

			<p>Restart sshd to apply the changes</p>

			<pre><code>systemctl restart sshd</code></pre>

			<h2>Test the Changes</h2>
			<p>From your client ssh into your server as normal. Instead of 
			connecting as you have been, you should now see a prompt for your 
			one time password. You can use <strong>oathtool</strong> to get 
			the code. Again, replace the long string of numbers and letters 
			with the secret key you generated on the server.</p>

			<pre><code>oathtool --totp -d6 <em>00112233445566aabbcc</em></code></pre>

			<p>Enter that 6 digit code into the prompt and you will be logged 
			into your server.</p>

			<p>Now, in the unlikely event that your SSH private key is stolen, 
			an attacker still won't be able to access your server!</p>

			<h2>Managing your TOTP</h2>
			<p>You probably don't want to run the oathtool command everytime you 
			need your code, and while you could make an alias, that would require 
			storing your secret key in plaintext. Here are some better options.</p>

			<ul>
					<li><strong>pass otp</strong> is an extension to the command-line 
					password manager <strong>pass</strong> for handling TOTP. 
					Use this if you are already using pass</li> 
					<li><strong>KeePassXC</strong> is a graphical password 
					manager that can manage TOTP</li> 
					<li><strong>Gnome Authenticator</strong> is a graphical 
					TOTP manager for the GNOME desktop environment</li>
			</ul>

			<p>You may also want to generate a QR code for easy setup on another 
			device.  Rerun the same oathtool command as before with the -v flag 
			to get the base32 version of your secret key.</p>

			<pre><code>oathtool --totp -v -d6 <em>00112233445566aabbcc</em>
--------------------------------
Hex secret: 00112233445566aabbcc
Base32 secret: <strong>AAISEM2EKVTKVO6M</strong>
Digits: 6
Window size: 0
TOTP mode: SHA1
Step size (seconds): 30
</code></pre>

			<p>Then use qrencode to generate the QR code image.</p>

			<pre><code>qrencode -o <em>totp.png</em> 'otpauth://totp/<em>user</em>@<em>server</em>?secret=<em>AAISEM2EKVTKVO6M</em>'</code></pre>

    </main>
	
<p>
<hr>
Consider <a href=../donate.html>donating</a> if this article was useful.
<a class=qr href=../images/bitcoin.png>[BTC]</a>
</p>
 	</main>
    <footer>
	<a href=../kb.html>Knowledge Base</a>
	<br>
	<a href=../index.html>www.chudnick.com</a>
	</footer>
</body>
</html>