Files
opnsense-carp-dhcp/opnsense-carp-dhcp-master.php

202 lines
6.4 KiB
PHP

#!/usr/local/bin/php
<?php
require_once("config.inc");
require_once("interfaces.inc");
require_once("util.inc");
require_once("filter.inc");
require_once("util.inc");
require_once("system.inc");
require_once('rrd.inc');
require_once('plugins.inc.d/webgui.inc');
/*
*/
# to get the $config, put file_put_contents('/root/config_php.log', print_r($config, true)); at the end of the /usr/local/opnsense/scripts/shell/setaddr.php file
# Locations:
# /usr/local/etc/inc
# /usr/local/opnsense/scripts/shell
# /usr/local/sbin/opnsense-shell
#############
# Variables #
#############
# Master Node/Router
$wanInterface = 'wan';
$gatewayName = 'WAN_GW';
$wanStaticIP = '192.168.101.1';
$wanStaticIPSubnet = '30';
# Backup Node/Router
$syncIP = $config['hasync']['synchronizetoip'];
$syncUsername = $config['hasync']['username'];
$syncPassword = $config['hasync']['password'];
###################
# Start of Script #
###################
function write_config_and_restart_services ($interface) {
write_config();
system_hosts_generate(true);
system_resolvconf_generate(true);
interface_bring_down($interface);
interface_configure(true, $interface, true);
plugins_configure('monitor', true);
filter_configure_sync(true);
webgui_configure_do(true);
rrd_configure(true);
}
if (count($argv) > 1) {
printf("Starting process to update gateway IP address. \n");
if (filter_var($argv[1], FILTER_VALIDATE_IP)) {
printf("IP %s is a valid IP. \n", $argv[1]);
printf("Updating gateway with name %s. \n", $gatewayName);
foreach ($config['gateways']['gateway_item'] as $i => $gateway) {
if ($gateway['name'] == $gatewayName) {
$config['gateways']['gateway_item'][$i]['gateway'] = $argv[1];
}
}
write_config_and_restart_services($wanInterface);
} else {
printf("Error: IP %s is not a valid IP. \n", $argv[1]);
}
printf("Finished process to update gateway IP address. \n");
return;
}
printf("Trying to ping sync host, %s. \n", $syncIP);
exec("ping -c 4 " . $syncIP, $output, $result);
if ($result == 0) {
printf("Ping is successful. No need to update. \n");
return;
}
printf("WAN Interface Name: %s \n", $wanInterface);
printf("Gateway Name: %s \n", $gatewayName);
printf("WAN Static IP: %s \n", $wanStaticIP);
printf("WAN Subnet: %s \n", $wanStaticIPSubnet);
printf("Sync IP: %s \n", $syncIP);
printf("Sync Username: %s \n", $syncUsername);
printf("Sync Password: <Redacted> \n");
printf("Setting WAN to DHCP. \n");
# Config for WAN DHCP and disable static gateway
$config['interfaces'][$wanInterface]['ipaddr'] = 'dhcp';
$config['interfaces'][$wanInterface]['subnet'] = '';
$config['interfaces'][$wanInterface]['gateway'] = '';
foreach ($config['gateways']['gateway_item'] as $i => $gateway) {
if ($gateway['name'] == $gatewayName) {
unset($config['gateways']['gateway_item'][$i]);
}
}
# set the config and reload everything to get a working DHCP
write_config_and_restart_services($wanInterface);
printf("Done setting WAN to DHCP. \n");
# DHCP ip address and gateway address
printf("Getting DHCP and Gateway IP Addresses. \n");
# get dHCP wan address and subnet
$iflist = legacy_config_get_interfaces(array('enable' => true, 'virtual' => false));
$ifdetails = legacy_interfaces_details();
if (!count($iflist)) {
echo "\n\tNo network interfaces are assigned.\n";
return;
}
$wanInfo = null;
foreach ($iflist as $ifname => $ifcfg) {
$class = null;
if ($ifcfg['descr'] == 'WAN') {
# this will have all the information about the WAN interface
$ifcfg['details'] = $ifdetails[$ifcfg['if']];
#print_r($ifcfg);
}
}
$wanIP = $ifcfg['details']['ipv4'][0]['ipaddr'];
$wanSubnet = $ifcfg['details']['ipv4'][0]['subnetbits'];
printf("WAN DHCP IP: %s \n", $wanIP);
printf("WAN DHCP Sbunet Bits: %s \n", $wanSubnet);
$gatewayIP = trim(shell_exec('netstat -rn | grep default | awk \'{print $2;}\''));
printf("Gateway IP: %s \n", $gatewayIP);
printf("Done getting DHCP and Gateway IP Addresses. \n");
printf("Setting WAN to Static based on the DHCP information. \n");
# Config for WAN Static
$config['interfaces'][$wanInterface]['ipaddr'] = $wanStaticIP;
$config['interfaces'][$wanInterface]['subnet'] = $wanStaticIPSubnet;
$config['interfaces'][$wanInterface]['gateway'] = $gatewayName;
# setup gateway
$gwCount = count($config['gateways']['gateway_item']);
$config['gateways']['gateway_item'][$gwCount]['gateway'] = $gatewayIP;
$config['gateways']['gateway_item'][$gwCount]['interface'] = $wanInterface;
$config['gateways']['gateway_item'][$gwCount]['name'] = $gatewayName;
$config['gateways']['gateway_item'][$gwCount]['ipprotocol'] = 'inet';
$config['gateways']['gateway_item'][$gwCount]['monitor_disable'] = 1;
$config['gateways']['gateway_item'][$gwCount]['defaultgw'] = 1;
$config['gateways']['gateway_item'][$gwCount]['fargw'] = 1;
# Loop through outbound nat and update the wan ip
foreach ($config['nat']['outbound']['rule'] as $i => $rule) {
if ($rule['interface'] == $wanInterface ) {
$config['nat']['outbound']['rule'][$i]['target'] = $wanIP;
}
}
# loop through carp addresses and update the wan ip address
foreach ($config['virtualip']['vip'] as $i => $vip) {
if ($vip['interface'] == $wanInterface) {
$config['virtualip']['vip'][$i]['subnet_bits'] = $wanSubnet;
$config['virtualip']['vip'][$i]['subnet'] = $wanIP;
$config['virtualip']['vip'][$i]['descr'] = "VIP WAN (GW: $gatewayIP)";
}
}
# set the config and reload everything to get a working DHCP
write_config_and_restart_services($wanInterface);
printf("Done Setting WAN to Static based on the DHCP information. \n");
printf("Sleeping for 30 seconds. \n");
sleep(30);
# try to sync carp settings to backup node/router
printf("Starting the CARP Sync. \n");
printf("Trying to ping sync host, %s. \n", $syncIP);
while (true) {
exec("ping -c 4 " . $syncIP, $output, $result);
if ($result == 0) {
printf("Ping is successful. \n");
break;
} else {
printf("Ping unsuccessful. \n");
}
}
$syncStatus = trim(shell_exec('configctl system ha_reconfigure_backup'));
printf("CARP Sync Status: %s. \n", $syncStatus);
printf("finished the CARP Sync. \n");
# still need a way to get the gateway configured on the backup router
# since I added the argv process, this can be placed on the backup router and this script can call it via ssh
# also should add a restart for unbound on carp status change