Project

General

Profile

Download (6.52 KB) Statistics
| Branch: | Tag: | Revision:
1 cb7d18d5 Renato Botelho
#!/usr/local/bin/php-cgi -f
2 5b237745 Scott Ullrich
<?php
3
/*
4 ac24dc24 Renato Botelho
 * sshd
5
 *
6
 * part of pfSense (https://www.pfsense.org)
7 c5d81585 Renato Botelho
 * Copyright (c) 2004 Fred Mol <fredmol@xs4all.nl>.
8 880ed461 jim-p
 * Copyright (c) 2004-2020 Rubicon Communications, LLC (Netgate)
9 ac24dc24 Renato Botelho
 * All rights reserved.
10
 *
11 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14 ac24dc24 Renato Botelho
 *
15 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
16 ac24dc24 Renato Botelho
 *
17 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22 ac24dc24 Renato Botelho
 */
23
24
require_once("globals.inc");
25
require_once("config.inc");
26
require_once("functions.inc");
27
require_once("shaper.inc");
28
29 3b73574b jim-p
if (!isset($config['system']['ssh']['enable'])) {
30 ac24dc24 Renato Botelho
	return;
31
}
32
33
$sshConfigDir = "/etc/ssh";
34
35
$keys = array(
36
	array('type' => 'rsa',     'suffix' => 'rsa_'),
37
	array('type' => 'ed25519', 'suffix' => 'ed25519_')
38
);
39
40
$keyfiles = array();
41
foreach ($keys as $key) {
42
	$keyfiles[] = "ssh_host_{$key['suffix']}key";
43
	$keyfiles[] = "ssh_host_{$key['suffix']}key.pub";
44
}
45
46
/*    if any of these files are 0 bytes then they are corrupted.
47
 *    remove them
48
 */
49
foreach ($keyfiles as $f2c) {
50
	if (!file_exists("{$sshConfigDir}/{$f2c}") || filesize("{$sshConfigDir}/{$f2c}") == 0) {
51
		/* Make sure we remove both files */
52
		unlink_if_exists($sshConfigDir . '/' . basename($f2c, ".pub"));
53
		unlink_if_exists($sshConfigDir . '/' . $f2c);
54
	}
55
}
56
57
if (!is_dir("/var/empty")) {
58
	/* make ssh home directory */
59
	mkdir("/var/empty", 0555);
60
}
61
62
if (!file_exists("/var/log/lastlog")) {
63
	/* Login related files. */
64
	@touch("/var/log/lastlog");
65
}
66
67
if (is_array($config['system']['ssh']) && !empty($config['system']['ssh']['port'])) {
68
	$sshport = $config['system']['ssh']['port'];
69
} else {
70
	$sshport = 22;
71
}
72
73
/* Include default configuration for pfSense */
74
/* Taken from https://stribika.github.io/2015/01/04/secure-secure-shell.html */
75
$sshconf = "# This file is automatically generated at startup\n";
76
$sshconf .= "KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256\n";
77
/* Run the server on another port if we have one defined */
78
$sshconf .= "Port $sshport\n";
79
/* Only allow protocol 2, because we say so */
80
$sshconf .= "Protocol 2\n";
81
foreach ($keys as $key) {
82
	$sshconf .= "HostKey {$sshConfigDir}/ssh_host_{$key['suffix']}key\n";
83
}
84 4cad9a5b jim-p
$sshconf .= "Compression delayed\n";
85 ac24dc24 Renato Botelho
$sshconf .= "ClientAliveInterval 30\n";
86
$sshconf .= "PermitRootLogin yes\n";
87 d6fdfd78 reb00tz
if ($config['system']['ssh']['sshdkeyonly'] == "both") {
88
	$sshconf .= "# Login via both Key and Password only\n";
89 aa9971a3 robjarsen
	$sshconf .= "AuthenticationMethods publickey,password\n";
90 d6fdfd78 reb00tz
	$sshconf .= "ChallengeResponseAuthentication yes\n";
91
	$sshconf .= "PasswordAuthentication yes\n";
92
	$sshconf .= "PubkeyAuthentication yes\n";
93
	$sshconf .= "UsePAM yes\n";
94
} else if (isset($config['system']['ssh']['sshdkeyonly'])) {
95 ac24dc24 Renato Botelho
	$sshconf .= "# Login via Key only\n";
96
	$sshconf .= "ChallengeResponseAuthentication no\n";
97
	$sshconf .= "PasswordAuthentication no\n";
98
	$sshconf .= "PubkeyAuthentication yes\n";
99 b35fc433 jim-p
	$sshconf .= "UsePAM no\n";
100 ac24dc24 Renato Botelho
} else {
101 d6fdfd78 reb00tz
	$sshconf .= "# Login via Key or Password\n";
102 ac24dc24 Renato Botelho
	$sshconf .= "ChallengeResponseAuthentication yes\n";
103
	$sshconf .= "PasswordAuthentication yes\n";
104
	$sshconf .= "PubkeyAuthentication yes\n";
105
}
106
$sshconf .= "UseDNS no\n";
107
$sshconf .= "LoginGraceTime 30s\n";
108
/* Hide FreeBSD version */
109
$sshconf .= "VersionAddendum none\n";
110 7b5e4508 Sorin Sbarnea
if (isset($config['system']['ssh']['sshdagentforwarding'])) {
111
	$sshconf .= "AllowAgentForwarding yes\n";
112
} else {
113
	$sshconf .= "AllowAgentForwarding no\n";
114
}
115 ac24dc24 Renato Botelho
$sshconf .= "X11Forwarding no\n";
116
$sshconf .= "Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr\n";
117
$sshconf .= "MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com\n";
118
$sshconf .= "# override default of no subsystems\n";
119
$sshconf .= "Subsystem\tsftp\t/usr/libexec/sftp-server\n";
120
121
/* Apply package SSHDCond settings if config file exists */
122
if (file_exists("/etc/sshd_extra")) {
123
	$fdExtra = fopen("/etc/sshd_extra", 'r');
124
	$szExtra = fread($fdExtra, 1048576); // Read up to 1MB from extra file
125
	$sshconf .= $szExtra;
126
	fclose($fdExtra);
127
}
128
129
/* Write the new sshd config file */
130
@file_put_contents("{$sshConfigDir}/sshd_config", $sshconf);
131
132
/* mop up from a badly implemented ssh keys -> cf backup */
133
if ($config['ssh']['dsa_key'] <> "") {
134
	unset($config['ssh']['dsa_key']);
135
	unset($config['ssh']['ecdsa_key']);
136
	unset($config['ssh']['ed25519_key']);
137
	unset($config['ssh']['rsa_key']);
138
	unset($config['ssh']['rsa1_key']);
139
	unset($config['ssh']['dsa']);
140
	unset($config['ssh']['rsa']);
141
	unset($config['ssh']['rsa1']);
142
	unset($config['ssh']['ak']);
143
	write_config("Clearing SSH keys from config.xml");
144
}
145
146
/* are we already running?  if so exit */
147
if (is_subsystem_dirty('sshdkeys')) {
148 2951a06a Renato Botelho
	unset($keys, $keyfiles);
149 ac24dc24 Renato Botelho
	return;
150
}
151
152
// Check for all needed key files. If any are missing, the keys need to be regenerated.
153
$generate_keys = array();
154
foreach ($keys as $key) {
155
	if (!file_exists("{$sshConfigDir}/ssh_host_{$key['suffix']}key") ||
156
	    !file_exists("{$sshConfigDir}/ssh_host_{$key['suffix']}key.pub")) {
157
		$generate_keys[] = $key;
158
	}
159
}
160
161
if (!empty($generate_keys)) {
162
	/* remove previous keys and regen later */
163
	file_notice("SSH", "{$g['product_name']} has started creating missing SSH keys.  SSH Startup will be delayed.  Please note that reloading the filter rules and changes will be delayed until this operation is completed.", "SSH KeyGen", "");
164
	mark_subsystem_dirty('sshdkeys');
165
	echo " Generating Keys:\n";
166
	foreach ($generate_keys as $key) {
167
		$_gb = exec("/usr/bin/nice -n20 /usr/bin/ssh-keygen -t {$key['type']} -b 4096 -N '' -f {$sshConfigDir}/ssh_host_{$key['suffix']}key");
168
	}
169
	clear_subsystem_dirty('sshdkeys');
170
	file_notice("SSH", "{$g['product_name']} has completed creating your SSH keys.  SSH is now started.", "SSH Startup", "");
171
}
172
173
/* kill existing sshd process, server only, not the childs */
174
$sshd_pid = exec("ps ax | egrep '/usr/sbin/[s]shd' | awk '{print $1}'");
175
if ($sshd_pid <> "") {
176
	echo "stopping ssh process $sshd_pid \n";
177
	@posix_kill($sshd_pid, SIGTERM);
178
}
179
/* Launch new server process */
180
$status = mwexec("/usr/sbin/sshd");
181
if ($status <> 0) {
182
	file_notice("sshd_startup", "SSHD failed to start.", "SSHD Daemon", "");
183
	echo "error!\n";
184
} else {
185
	echo "done.\n";
186
}
187
188
unset($keys, $keyfiles);
189 06e28ceb Ermal Lu?i
?>