Project

General

Profile

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