mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-18 10:35:27 +00:00
1266 lines
41 KiB
PHP
1266 lines
41 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Copyright (C) 2016-2019 Franco Fichtner <franco@opnsense.org>
|
|
* Copyright (C) 2004-2007 Scott Ullrich <sullrich@gmail.com>
|
|
* Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
function system_powerd_configure($verbose = false)
|
|
{
|
|
global $config;
|
|
|
|
if (is_process_running('powerd')) {
|
|
exec('/usr/bin/killall powerd');
|
|
}
|
|
|
|
if (!isset($config['system']['powerd_enable'])) {
|
|
return;
|
|
}
|
|
|
|
if ($verbose) {
|
|
echo 'Starting power daemon...';
|
|
flush();
|
|
}
|
|
|
|
$ac_mode = 'hadp';
|
|
if (!empty($config['system']['powerd_ac_mode'])) {
|
|
$ac_mode = $config['system']['powerd_ac_mode'];
|
|
}
|
|
|
|
$battery_mode = 'hadp';
|
|
if (!empty($config['system']['powerd_battery_mode'])) {
|
|
$battery_mode = $config['system']['powerd_battery_mode'];
|
|
}
|
|
|
|
$normal_mode = 'hadp';
|
|
if (!empty($config['system']['powerd_normal_mode'])) {
|
|
$normal_mode = $config['system']['powerd_normal_mode'];
|
|
}
|
|
|
|
mwexecf(
|
|
'/usr/sbin/powerd -b %s -a %s -n %s',
|
|
array($battery_mode, $ac_mode, $normal_mode)
|
|
);
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function get_default_sysctl_value($id)
|
|
{
|
|
$sysctls = array(
|
|
'debug.pfftpproxy' => '0',
|
|
'hw.syscons.kbd_reboot' => '0',
|
|
'hw.ibrs_disable' => '0',
|
|
'kern.ipc.maxsockbuf' => '4262144',
|
|
'kern.randompid' => '347',
|
|
'net.inet.icmp.drop_redirect' => '0',
|
|
'net.inet.icmp.icmplim' => '0',
|
|
'net.inet.icmp.log_redirect' => '0',
|
|
'net.inet.ip.accept_sourceroute' => '0',
|
|
'net.inet.ip.intr_queue_maxlen' => '1000',
|
|
'net.inet.ip.portrange.first' => '1024',
|
|
'net.inet.ip.random_id' => '1',
|
|
'net.inet.ip.redirect' => '1',
|
|
'net.inet.ip.sourceroute' => '0',
|
|
'net.inet.tcp.blackhole' => '2',
|
|
'net.inet.tcp.delayed_ack' => '0',
|
|
'net.inet.tcp.drop_synfin' => '1',
|
|
'net.inet.tcp.log_debug' => '0',
|
|
'net.inet.tcp.recvspace' => '65228',
|
|
'net.inet.tcp.sendspace' => '65228',
|
|
'net.inet.tcp.syncookies' => '1',
|
|
'net.inet.tcp.tso' => '1',
|
|
'net.inet.udp.blackhole' => '1',
|
|
'net.inet.udp.checksum' => 1,
|
|
'net.inet.udp.maxdgram' => '57344',
|
|
'net.inet6.ip6.prefer_tempaddr' => '0',
|
|
'net.inet6.ip6.redirect' => '1',
|
|
'net.inet6.ip6.use_tempaddr' => '0',
|
|
'net.link.bridge.pfil_bridge' => '0',
|
|
'net.link.bridge.pfil_local_phys' => '0',
|
|
'net.link.bridge.pfil_member' => '1',
|
|
'net.link.bridge.pfil_onlyip' => '0',
|
|
'net.link.tap.user_open' => '1',
|
|
'security.bsd.see_other_gids' => '0',
|
|
'security.bsd.see_other_uids' => '0',
|
|
'vfs.read_max' => '32',
|
|
'vm.pmap.pti' => '1',
|
|
);
|
|
|
|
if (isset($sysctls[$id])) {
|
|
return $sysctls[$id];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function system_sysctl_get()
|
|
{
|
|
global $config;
|
|
|
|
$sysctls = array(
|
|
'net.enc.in.ipsec_bpf_mask' => '2', /* after processing */
|
|
'net.enc.in.ipsec_filter_mask' => '2', /* after processing */
|
|
'net.enc.out.ipsec_bpf_mask' => '1', /* before processing */
|
|
'net.enc.out.ipsec_filter_mask' => '1', /* before processing */
|
|
);
|
|
|
|
if (isset($config['sysctl']['item'])) {
|
|
foreach($config['sysctl']['item'] as $tunable) {
|
|
if ($tunable['value'] == 'default') {
|
|
$value = get_default_sysctl_value($tunable['tunable']);
|
|
} else {
|
|
$value = $tunable['value'];
|
|
}
|
|
$sysctls[$tunable['tunable']] = $value;
|
|
}
|
|
}
|
|
|
|
return $sysctls;
|
|
}
|
|
|
|
function system_resolvconf_generate($verbose = false)
|
|
{
|
|
global $config;
|
|
|
|
$syscfg = config_read_array('system');
|
|
|
|
if ($verbose) {
|
|
echo 'Generating /etc/resolv.conf...';
|
|
flush();
|
|
}
|
|
|
|
$resolvconf = '';
|
|
if (!empty($syscfg['domain'])) {
|
|
$resolvconf = "domain {$syscfg['domain']}\n";
|
|
}
|
|
|
|
if (!isset($syscfg['dnslocalhost']) && (isset($config['dnsmasq']['enable']) || isset($config['unbound']['enable']))) {
|
|
$resolvconf .= "nameserver 127.0.0.1\n";
|
|
}
|
|
|
|
if (isset($syscfg['dnsallowoverride'])) {
|
|
foreach (get_searchdomains() as $searchserver) {
|
|
$resolvconf .= "search {$searchserver}\n";
|
|
}
|
|
foreach (get_nameservers() as $nameserver) {
|
|
$resolvconf .= "nameserver $nameserver\n";
|
|
}
|
|
}
|
|
|
|
if (isset($syscfg['dnsserver'][0])) {
|
|
foreach ($syscfg['dnsserver'] as $ns) {
|
|
$resolvconf .= "nameserver $ns\n";
|
|
}
|
|
}
|
|
|
|
$dnslock = lock('resolvconf', LOCK_EX);
|
|
|
|
file_put_contents('/etc/resolv.conf', $resolvconf);
|
|
chmod('/etc/resolv.conf', 0644);
|
|
|
|
/* setup static routes for DNS servers. */
|
|
for ($dnscounter = 1; $dnscounter < 9; $dnscounter++) {
|
|
/* setup static routes for dns servers */
|
|
$dnsgw = "dns{$dnscounter}gw";
|
|
if (isset($syscfg[$dnsgw])) {
|
|
$gwname = $syscfg[$dnsgw];
|
|
if (($gwname != '') && ($gwname != 'none')) {
|
|
$gatewayip = lookup_gateway_ip_by_name($gwname);
|
|
if (is_ipaddrv4($gatewayip)) {
|
|
/* dns server array starts at 0 */
|
|
$dnscountermo = $dnscounter - 1;
|
|
system_host_route($syscfg['dnsserver'][$dnscountermo], $gatewayip);
|
|
}
|
|
if (is_ipaddrv6($gatewayip)) {
|
|
/* dns server array starts at 0 */
|
|
$dnscountermo = $dnscounter - 1;
|
|
system_host_route($syscfg['dnsserver'][$dnscountermo], $gatewayip);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
unlock($dnslock);
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function get_locale_list()
|
|
{
|
|
$locales = array();
|
|
|
|
/* first one is the default */
|
|
$locales['en_US'] = gettext('English');
|
|
$locales['cs_CZ'] = gettext('Czech');
|
|
$locales['zh_CN'] = gettext('Chinese (Simplified)');
|
|
$locales['nl_NL'] = gettext('Dutch');
|
|
$locales['fr_FR'] = gettext('French');
|
|
$locales['de_DE'] = gettext('German');
|
|
$locales['it_IT'] = gettext('Italian');
|
|
$locales['ja_JP'] = gettext('Japanese');
|
|
$locales['pt_BR'] = gettext('Portuguese (Brazil)');
|
|
$locales['pt_PT'] = gettext('Portuguese (Portugal)');
|
|
$locales['ru_RU'] = gettext('Russian');
|
|
$locales['es_ES'] = gettext('Spanish');
|
|
$locales['tr_TR'] = gettext('Turkish');
|
|
|
|
return $locales;
|
|
}
|
|
|
|
function get_country_codes()
|
|
{
|
|
$dn_cc = array();
|
|
|
|
$iso3166_tab = '/usr/local/opnsense/contrib/tzdata/iso3166.tab';
|
|
if (file_exists($iso3166_tab)) {
|
|
$dn_cc_file = file($iso3166_tab);
|
|
foreach ($dn_cc_file as $line) {
|
|
if (preg_match('/^([A-Z][A-Z])\t(.*)$/', $line, $matches)) {
|
|
$dn_cc[$matches[1]] = trim($matches[2]);
|
|
}
|
|
}
|
|
}
|
|
return $dn_cc;
|
|
}
|
|
|
|
function get_zoneinfo()
|
|
{
|
|
$zones = timezone_identifiers_list(DateTimeZone::ALL ^ DateTimeZone::UTC);
|
|
|
|
$etcs = glob('/usr/share/zoneinfo/Etc/*');
|
|
foreach ($etcs as $etc) {
|
|
$zones[] = ltrim($etc, '/usr/share/zoneinfo/');
|
|
}
|
|
|
|
natsort($zones);
|
|
|
|
return $zones;
|
|
}
|
|
|
|
function get_searchdomains()
|
|
{
|
|
$master_list = array();
|
|
|
|
$search_list = glob('/var/etc/searchdomain_*');
|
|
|
|
if (is_array($search_list)) {
|
|
foreach ($search_list as $fdns) {
|
|
$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
if (!is_array($contents)) {
|
|
continue;
|
|
}
|
|
foreach ($contents as $dns) {
|
|
if (!empty($dns) && is_hostname($dns)) {
|
|
$master_list[] = $dns;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return array_unique($master_list);
|
|
}
|
|
|
|
function get_nameservers($interface = null)
|
|
{
|
|
$master_list = array();
|
|
|
|
$dns_lists = glob('/var/etc/nameserver_*');
|
|
|
|
if (!empty($interface)) {
|
|
/* only acquire servers provided for this interface */
|
|
$realif = get_real_interface($interface);
|
|
$realifv6 = get_real_interface($interface, 'inet6');
|
|
$dns_lists = array(
|
|
"/var/etc/nameserver_{$realif}",
|
|
"/var/etc/nameserver_v6{$realifv6}",
|
|
);
|
|
}
|
|
|
|
foreach ($dns_lists as $fdns) {
|
|
$contents = @file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
if (!is_array($contents)) {
|
|
continue;
|
|
}
|
|
foreach ($contents as $dns) {
|
|
if (!empty($dns) && is_ipaddr($dns)) {
|
|
$master_list[] = $dns;
|
|
}
|
|
}
|
|
}
|
|
|
|
return array_unique($master_list);
|
|
}
|
|
|
|
function system_hosts_generate($verbose = false)
|
|
{
|
|
global $config;
|
|
|
|
if ($verbose) {
|
|
echo 'Generating /etc/hosts...';
|
|
flush();
|
|
}
|
|
|
|
$syscfg = config_read_array('system');
|
|
|
|
$hosts = "127.0.0.1\tlocalhost localhost.{$syscfg['domain']}\n";
|
|
|
|
if (isset($config['interfaces']['lan'])) {
|
|
$cfgip = get_interface_ip("lan");
|
|
if (is_ipaddr($cfgip)) {
|
|
$hosts .= "{$cfgip}\t{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
|
|
}
|
|
} else {
|
|
foreach (array_keys(get_configured_interface_with_descr()) as $sysif) {
|
|
if (!interface_has_gateway($sysif)) {
|
|
$cfgip = get_interface_ip($sysif);
|
|
if (is_ipaddr($cfgip)) {
|
|
$hosts .= "{$cfgip}\t{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
file_put_contents('/etc/hosts', $hosts);
|
|
|
|
plugins_configure('hosts');
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function system_hostname_configure($verbose = false)
|
|
{
|
|
if ($verbose) {
|
|
echo 'Setting hostname: ';
|
|
flush();
|
|
}
|
|
|
|
$syscfg = config_read_array('system');
|
|
|
|
$hostname = "{$syscfg['hostname']}.{$syscfg['domain']}";
|
|
|
|
mwexecf('/bin/hostname %s', $hostname);
|
|
|
|
if ($verbose) {
|
|
echo "{$hostname}\n";
|
|
}
|
|
}
|
|
|
|
function system_host_route($host, $gateway, $delete = true, $add = true)
|
|
{
|
|
if (is_ipaddrv4($gateway)) {
|
|
$family = 'inet';
|
|
} elseif (is_ipaddrv6($gateway)) {
|
|
$family = 'inet6';
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
if ($delete) {
|
|
mwexecf('/sbin/route delete -host -%s %s', array($family, $host), true);
|
|
}
|
|
|
|
if ($add) {
|
|
mwexecf('/sbin/route add -host -%s %s %s', array($family, $host, $gateway));
|
|
}
|
|
}
|
|
|
|
function system_default_route($gateway, $family, $interface, $far = false)
|
|
{
|
|
$realif = get_real_interface($interface, $family == 'inet' ? 'all' : 'inet6');
|
|
|
|
switch ($family) {
|
|
case 'inet':
|
|
break;
|
|
case 'inet6':
|
|
if (is_linklocal($gateway)) {
|
|
$gateway .= "%{$realif}";
|
|
}
|
|
break;
|
|
default:
|
|
log_error("ROUTING: unknown address family '{$family}'");
|
|
return;
|
|
}
|
|
|
|
$tmpcmd = "/sbin/route -n get -{$family} default 2>/dev/null | /usr/bin/awk '/gateway:/ {print $2}'";
|
|
$current = trim(exec($tmpcmd), " \n");
|
|
if ($current == $gateway) {
|
|
log_error("ROUTING: keeping current default gateway '{$gateway}'");
|
|
return;
|
|
}
|
|
|
|
if ($family == 'inet') {
|
|
foreach (glob('/tmp/*_defaultgw', GLOB_BRACE) as $to_delete) {
|
|
log_error("ROUTING: removing {$to_delete}");
|
|
@unlink($to_delete);
|
|
}
|
|
|
|
log_error("ROUTING: creating /tmp/{$realif}_defaultgw using '{$gateway}'");
|
|
@file_put_contents("/tmp/{$realif}_defaultgw", $gateway);
|
|
|
|
if (!$far) {
|
|
$realif = null;
|
|
}
|
|
} else {
|
|
foreach (glob('/tmp/*_defaultgwv6', GLOB_BRACE) as $to_delete) {
|
|
log_error("ROUTING: removing {$to_delete}");
|
|
@unlink($to_delete);
|
|
}
|
|
|
|
log_error("ROUTING: creating /tmp/{$realif}_defaultgwv6 using '{$gateway}'");
|
|
@file_put_contents("/tmp/{$realif}_defaultgwv6", $gateway);
|
|
|
|
/* IPv6 does not support far gateway notion */
|
|
$realif = null;
|
|
}
|
|
|
|
mwexecf('/sbin/route delete -%s default', array($family), true);
|
|
if (!empty($realif)) {
|
|
mwexecf('/sbin/route delete -%s %s -interface %s', array($family, $gateway, $realif), true);
|
|
mwexecf('/sbin/route add -%s %s -interface %s', array($family, $gateway, $realif));
|
|
}
|
|
mwexecf('/sbin/route add -%s default %s', array($family, $gateway));
|
|
}
|
|
|
|
function system_routing_configure($verbose = false, $interface = '')
|
|
{
|
|
if ($verbose) {
|
|
echo 'Setting up routes...';
|
|
flush();
|
|
}
|
|
|
|
$interfacegw = '';
|
|
$foundgw = false;
|
|
$gatewayip = '';
|
|
$fargw = false;
|
|
|
|
$interfacegwv6 = '';
|
|
$foundgwv6 = false;
|
|
$gatewayipv6 = '';
|
|
|
|
if (!empty($interface)) {
|
|
log_error("ROUTING: entering configure using '${interface}'");
|
|
} else {
|
|
log_error("ROUTING: entering configure using defaults");
|
|
}
|
|
|
|
foreach (config_read_array('gateways', 'gateway_item') as $gateway) {
|
|
if (isset($gateway['defaultgw'])) {
|
|
if ($foundgw == false && $gateway['ipprotocol'] != 'inet6') {
|
|
if ($gateway['gateway'] == 'dynamic') {
|
|
$gateway['gateway'] = get_interface_gateway($gateway['interface']);
|
|
}
|
|
|
|
$interfacegw = $gateway['interface'];
|
|
$fargw = isset($gateway['fargw']);
|
|
$gatewayip = $gateway['gateway'];
|
|
$foundgw = true;
|
|
|
|
log_error("ROUTING: IPv4 default gateway set to {$interfacegw}");
|
|
} elseif ($foundgwv6 == false && $gateway['ipprotocol'] == 'inet6') {
|
|
if ($gateway['gateway'] == 'dynamic') {
|
|
$gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
|
|
}
|
|
|
|
$interfacegwv6 = $gateway['interface'];
|
|
$gatewayipv6 = $gateway['gateway'];
|
|
$foundgwv6 = true;
|
|
|
|
log_error("ROUTING: IPv6 default gateway set to {$interfacegwv6}");
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* From the looks of the code below we cannot cope with
|
|
* multi-WAN without setting explicit gateways. This is
|
|
* probably where the default gateway switching comes into
|
|
* play because this facility is allowed to use dynamically
|
|
* created gateways while the former code does not.
|
|
*
|
|
* In fact the following code is a mini gateway switcher
|
|
* facility which can only switch one hardcoded gateway and
|
|
* may obscure a problem with the setup for a long time... :(
|
|
*
|
|
* XXX Find a way to infer an upstream-capable interface or
|
|
* maybe make gateway switching the hardcoded behaviour, or
|
|
* at least the new default.
|
|
*/
|
|
|
|
if (!$foundgw) {
|
|
$interfacegw = 'wan';
|
|
log_error("ROUTING: no IPv4 default gateway set, assuming {$interfacegw}");
|
|
$gatewayip = get_interface_gateway($interfacegw);
|
|
}
|
|
|
|
if (!$foundgwv6) {
|
|
$interfacegwv6 = 'wan';
|
|
log_error("ROUTING: no IPv6 default gateway set, assuming {$interfacegwv6}");
|
|
$gatewayipv6 = get_interface_gateway_v6($interfacegwv6);
|
|
}
|
|
|
|
if ((empty($interface) || $interface == $interfacegw) && is_ipaddrv4($gatewayip)) {
|
|
log_error("ROUTING: setting IPv4 default route to {$gatewayip}");
|
|
system_default_route($gatewayip, 'inet', $interfacegw, $fargw);
|
|
} else {
|
|
log_error("ROUTING: skipping IPv4 default route");
|
|
}
|
|
|
|
if ((empty($interface) || $interface == $interfacegwv6) && is_ipaddrv6($gatewayipv6)) {
|
|
log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}");
|
|
system_default_route($gatewayipv6, 'inet6', $interfacegwv6);
|
|
} else {
|
|
log_error("ROUTING: skipping IPv6 default route");
|
|
}
|
|
|
|
system_staticroutes_configure($interface);
|
|
|
|
set_sysctl(array(
|
|
'net.inet.ip.forwarding' => '1',
|
|
'net.inet6.ip6.forwarding' => '1',
|
|
));
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function system_staticroutes_configure($interface = '')
|
|
{
|
|
$static_routes = get_staticroutes(false, true);
|
|
if (count($static_routes)) {
|
|
$ifdetails = legacy_interfaces_details();
|
|
$gateways_arr = (new \OPNsense\Routing\Gateways($ifdetails))->gatewaysIndexedByName(false, true);
|
|
foreach ($static_routes as $rtent) {
|
|
if (empty($gateways_arr[$rtent['gateway']])) {
|
|
log_error(sprintf('Static Routes: Gateway IP could not be found for %s', $rtent['network']));
|
|
continue;
|
|
}
|
|
$gateway = $gateways_arr[$rtent['gateway']];
|
|
if (!empty($interface) && $interface != $gateway['friendlyiface']) {
|
|
continue;
|
|
}
|
|
|
|
if (!is_subnet($rtent['network'])) {
|
|
log_error(sprintf('Cannot add static route to: %s', $rtent['network']));
|
|
continue;
|
|
}
|
|
$interfacegw = $gateway['if'];
|
|
$gatewayip = $gateway['gateway'];
|
|
$fargw = isset($gateway['fargw']) && $gateway['ipprotocol'] != 'inet6';
|
|
$blackhole = '';
|
|
|
|
switch ($rtent['gateway']) {
|
|
case 'Null4':
|
|
case 'Null6':
|
|
$blackhole = '-blackhole';
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
$ip = $rtent['network'];
|
|
if (!empty($rtent['disabled'])) {
|
|
$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
|
|
mwexec("/sbin/route delete {$inet} " . escapeshellarg($ip), true);
|
|
} else {
|
|
$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
|
|
$cmd = " {$inet} {$blackhole} " . escapeshellarg($ip) . " ";
|
|
if (is_ipaddr($gatewayip)) {
|
|
mwexec("/sbin/route delete".$cmd . escapeshellarg($gatewayip), true);
|
|
if ($fargw) {
|
|
mwexecf('/sbin/route delete %s %s -interface %s ', array($inet, $gatewayip, $interfacegw), true);
|
|
mwexecf('/sbin/route add %s %s -interface %s', array($inet, $gatewayip, $interfacegw), true);
|
|
} elseif (is_linklocal($gatewayip) && strpos($gatewayip, '%') === false) {
|
|
$gatewayip .= "%{$interfacegw}";
|
|
}
|
|
mwexec("/sbin/route add".$cmd . escapeshellarg($gatewayip), true);
|
|
} elseif (!empty($interfacegw)) {
|
|
mwexec("/sbin/route delete".$cmd . "-interface " . escapeshellarg($interfacegw), true);
|
|
mwexec("/sbin/route add".$cmd . "-interface " . escapeshellarg($interfacegw), true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function system_syslogd_fixup_server($server)
|
|
{
|
|
/* If it's an IPv6 IP alone, encase it in brackets */
|
|
if (is_ipaddrv6($server)) {
|
|
return "[$server]";
|
|
} else {
|
|
return $server;
|
|
}
|
|
}
|
|
|
|
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
|
|
// Rather than repeatedly use the same code, use this function to build a list of remote servers.
|
|
$facility .= " ".
|
|
$remote_servers = "";
|
|
$pad_to = 56;
|
|
$padding = ceil(($pad_to - strlen($facility))/8)+1;
|
|
if(!empty($syslogcfg['remoteserver'])) {
|
|
$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
|
|
}
|
|
if(!empty($syslogcfg['remoteserver2'])) {
|
|
$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
|
|
}
|
|
if(!empty($syslogcfg['remoteserver3'])) {
|
|
$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
|
|
}
|
|
return $remote_servers;
|
|
}
|
|
|
|
function system_syslogd_extra_local($logsocket)
|
|
{
|
|
$logdir = dirname($logsocket);
|
|
|
|
if (!is_dir($logdir)) {
|
|
/* create if needed to avoid startup error */
|
|
mwexecf('/bin/mkdir -p %s', $logdir);
|
|
}
|
|
|
|
/* emit extra args for syslogd invoke */
|
|
return exec_safe('-l %s ', $logsocket);
|
|
}
|
|
|
|
function system_syslogd_start($verbose = false, $restart = false)
|
|
{
|
|
if ($verbose) {
|
|
echo 'Configuring system logging...';
|
|
flush();
|
|
}
|
|
|
|
configd_run('template reload OPNsense/Syslog');
|
|
|
|
$syslogcfg = config_read_array('syslog');
|
|
|
|
$log_directive = '%';
|
|
$syslogd_extra = '';
|
|
|
|
$syslogconf = '';
|
|
|
|
$syslogconfs = array();
|
|
|
|
foreach (plugins_syslog() as $plugin_name => $plugin_details) {
|
|
$syslogconfs[$plugin_name] = $plugin_details;
|
|
}
|
|
|
|
/*
|
|
* XXX Standard syslog configs overwrite plugins, but we can
|
|
* get rid of this behaviour by wrapping this local array using
|
|
* the key as a "name" entry in the array...
|
|
*/
|
|
$syslogconfs['configd'] = array('facility' => array('configd.py'));
|
|
$syslogconfs['dhcpd'] = array('facility' => array('dhcpd', 'dhcrelay'), 'local' => '/var/dhcpd/var/run/log', 'remote' => 'dhcp');
|
|
$syslogconfs['filter'] = array('facility' => array('filterlog'), 'remote' => 'filter');
|
|
$syslogconfs['gateways'] = array('facility' => array('dpinger'), 'remote' => 'apinger');
|
|
$syslogconfs['lighttpd'] = array('facility' => array('lighttpd'));
|
|
$syslogconfs['pkg'] = array('facility' => array('pkg', 'pkg-static'));
|
|
$syslogconfs['portalauth'] = array('facility' => array('captiveportal'), 'remote' => 'portalauth');
|
|
$syslogconfs['ppps'] = array('facility' => array('ppp'));
|
|
$syslogconfs['resolver'] = array('facility' => array('unbound'), 'local' => '/var/unbound/var/run/log', 'remote' => 'dns');
|
|
$syslogconfs['routing'] = array('facility' => array('radvd', 'routed', 'rtsold', 'olsrd', 'zebra', 'ospfd', 'bgpd', 'miniupnpd'));
|
|
$syslogconfs['wireless'] = array('facility' => array('hostapd'), 'remote' => 'hostapd');
|
|
|
|
$separatelogfacilities = array();
|
|
foreach ($syslogconfs as $logTopic => $logConfig) {
|
|
$syslogconf .= "!".implode(',', $logConfig['facility'])."\n";
|
|
$separatelogfacilities = array_merge($logConfig['facility'], $separatelogfacilities);
|
|
if (!isset($syslogcfg['disablelocallogging'])) {
|
|
$syslogconf .= "*.* {$log_directive}/var/log/{$logTopic}.log\n";
|
|
}
|
|
if (!empty($logConfig['remote']) && !empty($syslogcfg[$logConfig['remote']]) && !empty($syslogcfg['enable'])) {
|
|
$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
|
|
}
|
|
if (!empty($logConfig['local'])) {
|
|
$syslogd_extra .= system_syslogd_extra_local($logConfig['local']);
|
|
}
|
|
}
|
|
|
|
asort($separatelogfacilities);
|
|
$facilitylist = implode(',', array_unique($separatelogfacilities));
|
|
$syslogconf .= "!-{$facilitylist}\n";
|
|
if (!isset($syslogcfg['disablelocallogging'])) {
|
|
/* XXX non-system local redirects look unused */
|
|
$syslogconf .= <<<EOD
|
|
local3.* {$log_directive}/var/log/vpn.log
|
|
local4.* {$log_directive}/var/log/portalauth.log
|
|
local7.* {$log_directive}/var/log/dhcpd.log
|
|
*.notice;kern.debug;lpr.info;mail.crit;daemon.none {$log_directive}/var/log/system.log
|
|
news.err;local0.none;local3.none;local4.none {$log_directive}/var/log/system.log
|
|
local7.none {$log_directive}/var/log/system.log
|
|
security.* {$log_directive}/var/log/system.log
|
|
auth.info;authpriv.info;daemon.info {$log_directive}/var/log/system.log
|
|
auth.info;authpriv.info;user.* |exec /usr/local/sbin/sshlockout_pf 15
|
|
*.emerg *
|
|
|
|
EOD;
|
|
}
|
|
if (!empty($syslogcfg['enable'])) {
|
|
/* XXX most remote facilities are already sent to remote using the 'remote' keyword */
|
|
if (isset($syslogcfg['system'])) {
|
|
$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, '*.notice;kern.debug;lpr.info;mail.crit;daemon.none');
|
|
$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, 'news.err;local0.none;local3.none;local4.none');
|
|
$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, 'local7.none');
|
|
$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, 'security.*');
|
|
$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, 'auth.info;authpriv.info;daemon.info');
|
|
$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, '*.emerg');
|
|
}
|
|
if (isset($syslogcfg['logall'])) {
|
|
// Make everything mean everything, including facilities excluded above.
|
|
$syslogconf .= "!*\n";
|
|
$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, '*.*');
|
|
}
|
|
}
|
|
|
|
file_put_contents('/var/etc/syslog.conf', $syslogconf);
|
|
|
|
if (!empty($syslogcfg['sourceip'])) {
|
|
$ifaddr = $syslogcfg['ipproto'] == 'ipv6' ?
|
|
get_interface_ipv6($syslogcfg['sourceip']) :
|
|
get_interface_ip($syslogcfg['sourceip']);
|
|
if (is_ipaddr($ifaddr)) {
|
|
$syslogd_extra .= exec_safe('-b %s ', $ifaddr);
|
|
}
|
|
}
|
|
|
|
$syslogd_extra .= exec_safe('-f %s ', '/var/etc/syslog.conf');
|
|
|
|
// setup log files for all facilities including default
|
|
$default_logfile_size = !empty($syslogcfg['logfilesize']) ? $syslogcfg['logfilesize'] : '511488';
|
|
$syslog_files = array_keys($syslogconfs);
|
|
$syslog_files = array_merge($syslog_files, array('system', 'vpn'));
|
|
foreach ($syslog_files as $syslog_fn) {
|
|
$filename = "/var/log/".basename($syslog_fn).".log";
|
|
if (!file_exists($filename)) {
|
|
mwexecf('/usr/local/sbin/clog -i -s %s %s', array($default_logfile_size, $filename));
|
|
}
|
|
mwexecf('chmod 0600 %s', array($filename));
|
|
}
|
|
|
|
if (!$restart && isvalidpid('/var/run/syslog.pid')) {
|
|
killbypid('/var/run/syslog.pid', 'HUP');
|
|
} else {
|
|
killbypid('/var/run/syslog.pid', 'TERM', true);
|
|
mwexecf("/usr/local/sbin/syslogd -s -c -c -P %s {$syslogd_extra}", '/var/run/syslog.pid');
|
|
}
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function system_clear_log($logfile, $restart_syslogd = true)
|
|
{
|
|
if ($restart_syslogd) {
|
|
killbyname('syslogd');
|
|
}
|
|
|
|
foreach (glob($logfile . '.*') as $rotated) {
|
|
@unlink($rotated);
|
|
}
|
|
|
|
/* preserve file ownership and permissions */
|
|
if (file_exists($logfile)) {
|
|
$handle = fopen($logfile, 'r+');
|
|
if ($handle) {
|
|
ftruncate($handle, 0);
|
|
fclose($handle);
|
|
}
|
|
}
|
|
|
|
if ($restart_syslogd) {
|
|
system_syslogd_start();
|
|
}
|
|
}
|
|
|
|
function system_clear_clog($logfile, $restart_syslogd = true)
|
|
{
|
|
if ($restart_syslogd) {
|
|
killbyname('syslogd');
|
|
}
|
|
|
|
$syslogcfg = config_read_array('syslog');
|
|
|
|
$log_size = isset($syslogcfg['logfilesize']) ? $syslogcfg['logfilesize'] : '511488';
|
|
mwexecf('/usr/local/sbin/clog -i -s %s %s', array($log_size, $logfile));
|
|
|
|
if ($restart_syslogd) {
|
|
system_syslogd_start();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* get_memory()
|
|
* returns an array listing the amount of
|
|
* memory installed in the hardware
|
|
* [0] net memory available for the OS (FreeBSD) after some is taken by BIOS, video or whatever - e.g. 235 MBytes
|
|
* [1] real (actual) memory of the system, should be the size of the RAM card/s - e.g. 256 MBytes
|
|
*/
|
|
function get_memory() {
|
|
$physmem = get_single_sysctl("hw.physmem");
|
|
$realmem = get_single_sysctl("hw.realmem");
|
|
/* convert from bytes to megabytes */
|
|
return array(($physmem/1048576),($realmem/1048576));
|
|
}
|
|
|
|
function system_firmware_configure($verbose = false)
|
|
{
|
|
global $config, $g;
|
|
|
|
if ($verbose) {
|
|
echo 'Writing firmware setting...';
|
|
flush();
|
|
}
|
|
|
|
/* rewrite the config via the defaults */
|
|
$origin_conf = '/usr/local/etc/pkg/repos/OPNsense.conf';
|
|
copy("{$origin_conf}.sample", $origin_conf);
|
|
|
|
if (!empty($config['system']['firmware']['mirror'])) {
|
|
mwexecf(
|
|
'/usr/local/sbin/opnsense-update %s %s',
|
|
array('-sm', str_replace('/', '\/', $config['system']['firmware']['mirror']))
|
|
);
|
|
}
|
|
|
|
if (!empty($config['system']['firmware']['flavour'])) {
|
|
mwexecf(
|
|
'/usr/local/sbin/opnsense-update -sn %s',
|
|
str_replace('/', '\/', sprintf(
|
|
"%s{$config['system']['firmware']['flavour']}",
|
|
/* if there is no directory slash we always treat it with default ABI prefix */
|
|
strpos($config['system']['firmware']['flavour'], '/') === false ? "${g['product_abi']}/" : ''
|
|
))
|
|
);
|
|
}
|
|
|
|
$ca_root_nss = '/usr/local/share/certs/ca-root-nss.crt';
|
|
$ca_cert_pem = '/usr/local/openssl/cert.pem';
|
|
if (file_exists($ca_root_nss)) {
|
|
$ca = file_get_contents($ca_root_nss);
|
|
foreach (config_read_array('ca') as $entry) {
|
|
if (!empty($entry['crt'])) {
|
|
$ca .= "\n# {$entry['descr']}\n" . str_replace("\r", '', base64_decode($entry['crt']));
|
|
}
|
|
}
|
|
|
|
file_put_contents($ca_cert_pem, $ca);
|
|
copy($ca_cert_pem, '/usr/local/etc/ssl/cert.pem');
|
|
@unlink('/etc/ssl/cert.pem'); /* do not clobber symlink target */
|
|
copy($ca_cert_pem, '/etc/ssl/cert.pem');
|
|
}
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function system_timezone_configure($verbose = false)
|
|
{
|
|
$syscfg = config_read_array('system');
|
|
|
|
if ($verbose) {
|
|
echo 'Setting timezone...';
|
|
flush();
|
|
}
|
|
|
|
/* extract appropriate timezone file */
|
|
$timezone = $syscfg['timezone'];
|
|
$timezones = get_zoneinfo();
|
|
|
|
/* reset to default if empty or nonexistent */
|
|
if (empty($timezone) || !in_array($timezone, $timezones) ||
|
|
!file_exists(sprintf('/usr/share/zoneinfo/%s', $timezone))) {
|
|
$timezone = 'Etc/UTC';
|
|
}
|
|
|
|
/* apply timezone */
|
|
if (file_exists(sprintf('/usr/share/zoneinfo/%s', $timezone))) {
|
|
copy(sprintf('/usr/share/zoneinfo/%s', $timezone), '/etc/localtime');
|
|
}
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function system_sysctl_configure($verbose = false)
|
|
{
|
|
if ($verbose) {
|
|
echo 'Setting up extended sysctls...';
|
|
flush();
|
|
}
|
|
|
|
set_sysctl(system_sysctl_get());
|
|
system_arp_wrong_if();
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function system_arp_wrong_if()
|
|
{
|
|
global $config;
|
|
|
|
set_sysctl(array(
|
|
'net.link.ether.inet.log_arp_wrong_iface' => isset($config['system']['sharednet']) ? '0' : '1',
|
|
'net.link.ether.inet.log_arp_movements' => isset($config['system']['sharednet']) ? '0' : '1',
|
|
));
|
|
}
|
|
|
|
function system_kernel_configure($verbose = false)
|
|
{
|
|
global $config;
|
|
|
|
if ($verbose) {
|
|
echo 'Configuring kernel modules...';
|
|
flush();
|
|
}
|
|
|
|
/*
|
|
* Vital kernel modules can go missing on reboot due to
|
|
* /boot/loader.conf not materialising. This is still
|
|
* an UFS problem, despite claims otherwise. In any case,
|
|
* load all the modules again to make sure.
|
|
*
|
|
* Keep in sync with /usr/local/etc/erc.loader.d/20-modules
|
|
*/
|
|
$mods = array(
|
|
'carp',
|
|
'if_bridge',
|
|
'if_enc',
|
|
'if_gif',
|
|
'if_gre',
|
|
'if_lagg',
|
|
'if_tap',
|
|
'if_tun',
|
|
'if_vlan',
|
|
'pf',
|
|
'pflog',
|
|
'pfsync',
|
|
);
|
|
|
|
if (!empty($config['system']['crypto_hardware'])) {
|
|
log_error(sprintf('Loading %s cryptographic accelerator module.', $config['system']['crypto_hardware']));
|
|
$mods[] = $config['system']['crypto_hardware'];
|
|
}
|
|
|
|
if (!empty($config['system']['cryptodev_enable'])) {
|
|
log_error('Loading cryptodev kernel module.');
|
|
$mods[] = 'cryptodev';
|
|
}
|
|
|
|
if (!empty($config['system']['thermal_hardware'])) {
|
|
log_error(sprintf('Loading %s thermal monitor module.', $config['system']['thermal_hardware']));
|
|
$mods[] = $config['system']['thermal_hardware'];
|
|
}
|
|
|
|
foreach ($mods as $mod) {
|
|
mwexecf('/sbin/kldload %s', $mod, true);
|
|
}
|
|
|
|
/* we now have /dev/pf, time to fix permissions for proxies */
|
|
chgrp('/dev/pf', 'proxy');
|
|
chmod('/dev/pf', 0660);
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function system_devd_configure($verbose = false)
|
|
{
|
|
if ($verbose) {
|
|
echo 'Starting device manager...';
|
|
flush();
|
|
}
|
|
|
|
exec('/sbin/devd');
|
|
/* historic sleep */
|
|
sleep(1);
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function system_cron_configure($verbose = false, $defer = false)
|
|
{
|
|
function generate_cron_job($command, $minute = '0', $hour = '*', $monthday = '*', $month = '*', $weekday = '*')
|
|
{
|
|
$cron_item = array();
|
|
|
|
$cron_item['minute'] = $minute;
|
|
$cron_item['hour'] = $hour;
|
|
$cron_item['mday'] = $monthday;
|
|
$cron_item['month'] = $month;
|
|
$cron_item['wday'] = $weekday;
|
|
$cron_item['command'] = $command;
|
|
|
|
return $cron_item;
|
|
}
|
|
|
|
$autocron = array();
|
|
|
|
if ($verbose) {
|
|
echo 'Configuring CRON...';
|
|
flush();
|
|
}
|
|
|
|
foreach (plugins_cron() as $cron_plugin) {
|
|
/*
|
|
* We are stuffing jobs inside 'autocron' to be able to
|
|
* deprecate this at a later time. Ideally all of the
|
|
* services should use a single cron-model, which this is
|
|
* not. At least this plugin function helps us to divide
|
|
* and conquer the code bits... :)
|
|
*/
|
|
if (!empty($cron_plugin['autocron'])) {
|
|
$autocron[] = call_user_func_array('generate_cron_job', $cron_plugin['autocron']);
|
|
}
|
|
}
|
|
|
|
$crontab_contents = "# DO NOT EDIT THIS FILE -- OPNsense auto-generated file\n";
|
|
$crontab_contents .= "#\n";
|
|
$crontab_contents .= "# User-defined crontab files can be loaded via /etc/cron.d\n";
|
|
$crontab_contents .= "# or /usr/local/etc/cron.d and follow the same format as\n";
|
|
$crontab_contents .= "# /etc/crontab, see the crontab(5) manual page.\n";
|
|
$crontab_contents .= "SHELL=/bin/sh\n";
|
|
$crontab_contents .= "PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin\n";
|
|
$crontab_contents .= "#minute\thour\tmday\tmonth\twday\tcommand\n";
|
|
|
|
foreach ($autocron as $item) {
|
|
$crontab_contents .= "{$item['minute']}\t";
|
|
$crontab_contents .= "{$item['hour']}\t";
|
|
$crontab_contents .= "{$item['mday']}\t";
|
|
$crontab_contents .= "{$item['month']}\t";
|
|
$crontab_contents .= "{$item['wday']}\t";
|
|
$crontab_contents .= "({$item['command']}) > /dev/null\n";
|
|
}
|
|
|
|
file_put_contents('/var/cron/tabs/root', $crontab_contents);
|
|
|
|
if (!$defer) {
|
|
configd_run('cron restart');
|
|
}
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
}
|
|
|
|
function system_console_mutable()
|
|
{
|
|
/* this function name is a pun :) */
|
|
|
|
global $config;
|
|
|
|
return isset($config['system']['primaryconsole']) &&
|
|
($config['system']['primaryconsole'] == 'serial' ||
|
|
$config['system']['primaryconsole'] == 'null');
|
|
}
|
|
|
|
function system_console_mute()
|
|
{
|
|
if (system_console_mutable()) {
|
|
exec('/sbin/conscontrol mute on');
|
|
}
|
|
}
|
|
|
|
function system_console_unmute()
|
|
{
|
|
if (system_console_mutable()) {
|
|
exec('/sbin/conscontrol mute off');
|
|
}
|
|
}
|
|
|
|
function system_console_types()
|
|
{
|
|
return array(
|
|
/* sorted by usage */
|
|
'video' => array('value' => 'vidconsole', 'name' => gettext('VGA Console')),
|
|
'serial' => array('value' => 'comconsole', 'name' => gettext('Serial Console')),
|
|
'efi' => array('value' => 'efi', 'name' => gettext('EFI Console')),
|
|
'null' => array('value' => 'nullconsole', 'name' => gettext('Mute Console')),
|
|
);
|
|
}
|
|
|
|
function system_login_configure($verbose = false)
|
|
{
|
|
global $config;
|
|
|
|
if ($verbose) {
|
|
echo 'Configuring login behaviour...';
|
|
flush();
|
|
}
|
|
|
|
/* depends on user account locking */
|
|
local_sync_accounts();
|
|
|
|
configd_run('template reload OPNsense/Auth');
|
|
|
|
$serialspeed = (!empty($config['system']['serialspeed']) && is_numeric($config['system']['serialspeed'])) ? $config['system']['serialspeed'] : '115200';
|
|
|
|
$new_boot_config = array();
|
|
$new_boot_config['comconsole_speed'] = null;
|
|
$new_boot_config['boot_multicons'] = null;
|
|
$new_boot_config['boot_serial'] = null;
|
|
$new_boot_config['kern.vty'] = null;
|
|
$new_boot_config['console'] = null;
|
|
|
|
$console_types = system_console_types();
|
|
$console_selection = array();
|
|
|
|
foreach (array('primaryconsole', 'secondaryconsole') as $console_order) {
|
|
if (!empty($config['system'][$console_order]) && isset($console_types[$config['system'][$console_order]])) {
|
|
$console_selection[] = $console_types[$config['system'][$console_order]]['value'];
|
|
}
|
|
}
|
|
|
|
$console_selection = array_unique($console_selection);
|
|
|
|
$output_enabled = count($console_selection) != 1 || !in_array('nullconsole', $console_selection);
|
|
$virtual_enabled = !count($console_selection) || in_array('vidconsole', $console_selection) ||
|
|
in_array('efi', $console_selection);
|
|
$serial_enabled = in_array('comconsole', $console_selection);
|
|
|
|
if (count($console_selection)) {
|
|
$new_boot_config['console'] = '"' . implode(',', $console_selection) . '"';
|
|
if (count($console_selection) >= 2) {
|
|
$new_boot_config['boot_multicons'] = '"YES"';
|
|
}
|
|
}
|
|
|
|
if ($serial_enabled) {
|
|
@file_put_contents('/boot.config', "-S{$serialspeed} -D\n");
|
|
$new_boot_config['comconsole_speed'] = '"'.$serialspeed.'"';
|
|
$new_boot_config['boot_serial'] = '"YES"';
|
|
} elseif (!$output_enabled) {
|
|
@file_put_contents('/boot.config', "-q -m\n");
|
|
} else {
|
|
@unlink('/boot.config');
|
|
}
|
|
|
|
if (empty($config['system']['usevirtualterminal'])) {
|
|
$new_boot_config['kern.vty'] = '"sc"';
|
|
}
|
|
|
|
/* reload static values from rc.loader.d */
|
|
mwexecf('/usr/local/etc/rc.loader');
|
|
|
|
/* copy settings already there */
|
|
$new_loader_conf = @file_get_contents('/boot/loader.conf');
|
|
|
|
$new_loader_conf .= "# dynamically generated tunables settings follow\n";
|
|
foreach (system_sysctl_get() as $param => $value) {
|
|
$new_loader_conf .= "{$param}=\"{$value}\"\n";
|
|
}
|
|
$new_loader_conf .= "\n";
|
|
|
|
$new_loader_conf .= "# dynamically generated console settings follow\n";
|
|
foreach ($new_boot_config as $param => $value) {
|
|
if (!empty($value)) {
|
|
$new_loader_conf .= "{$param}={$value}\n";
|
|
} else {
|
|
$new_loader_conf .= "#${param}\n";
|
|
}
|
|
}
|
|
|
|
/* write merged file back to target location */
|
|
@file_put_contents('/boot/loader.conf', $new_loader_conf);
|
|
|
|
/* setup /etc/ttys */
|
|
$etc_ttys_lines = explode("\n", file_get_contents('/etc/ttys'));
|
|
$fd = fopen('/etc/ttys', 'w');
|
|
$on_off_secure_u = $serial_enabled ? 'onifconsole secure' : 'off secure';
|
|
$on_off_secure_v = $virtual_enabled ? 'on secure' : 'off secure';
|
|
/* XXX serial type uses 3wire nowadays */
|
|
if (isset($config['system']['disableconsolemenu'])) {
|
|
$console_type = 'Pc';
|
|
$serial_type = 'std.' . $serialspeed;
|
|
} else {
|
|
$console_type = 'al.Pc';
|
|
$serial_type = 'al.' . $serialspeed;
|
|
}
|
|
foreach ($etc_ttys_lines as $tty) {
|
|
/* virtual terminals */
|
|
foreach (array('ttyv0', 'ttyv1', 'ttyv2', 'ttyv3', 'ttyv4', 'ttyv5', 'ttyv6', 'ttyv7') as $virtualport) {
|
|
if (strpos($tty, $virtualport) === 0) {
|
|
fwrite($fd, "{$virtualport}\t\"/usr/libexec/getty {$console_type}\"\t\txterm\t${on_off_secure_v}\n");
|
|
continue 2;
|
|
}
|
|
}
|
|
/* serial terminals */
|
|
foreach (array('tty%s0', 'tty%s1', 'tty%s2', 'tty%s3') as $serialport) {
|
|
$serialport = sprintf($serialport, isset($config['system']['serialusb']) ? 'U' : 'u');
|
|
if (stripos($tty, $serialport) === 0) {
|
|
fwrite($fd, "{$serialport}\t\"/usr/libexec/getty {$serial_type}\"\tvt100\t{$on_off_secure_u}\n");
|
|
continue 2;
|
|
}
|
|
}
|
|
|
|
if (!empty($tty)) {
|
|
/* all other lines stay the same */
|
|
fwrite($fd, $tty . "\n");
|
|
}
|
|
}
|
|
fclose($fd);
|
|
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
|
|
/* force init(8) to reload /etc/ttys */
|
|
exec('/bin/kill -HUP 1');
|
|
}
|
|
|
|
function reset_factory_defaults($sync = true)
|
|
{
|
|
mwexec('/bin/rm -fr /conf/* /var/log/* /root/.history');
|
|
disable_security_checks();
|
|
|
|
mwexec('/usr/local/sbin/beep.sh stop');
|
|
|
|
/* as we go through a special case directly shut down */
|
|
$shutdown_cmd = '/sbin/shutdown -op now';
|
|
if ($sync) {
|
|
mwexec($shutdown_cmd);
|
|
} else {
|
|
mwexec_bg($shutdown_cmd);
|
|
}
|
|
}
|