Skip to content

Instantly share code, notes, and snippets.

@stuudmuffin
Last active September 6, 2023 14:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stuudmuffin/ebf7a37ed85242bab24afa05ab2a6094 to your computer and use it in GitHub Desktop.
Save stuudmuffin/ebf7a37ed85242bab24afa05ab2a6094 to your computer and use it in GitHub Desktop.
PHP api applicator to simply add ip's to an ip firewall access-list. Now with javascript countdown timer!
<?php
/*
When you add an ssh key to a mikrotik user, ssh still gives a password prompt.
A valid key will make password login fail on ssh, but hackers don't know that.
They'll keep trying to pry in, forever fruitless. This is really just annoying
on the logs. So I created a firewall rule to drop traffic on port 22 unless the
source ip exists inside of a defined "ssh_whitelist". To add myself to this list,
I have a webserver on the network I can get to through https login, and simply
add my IP with this script. I have custom formatting on my own page, of course.
I've left formatting to the minimum here. You have the power to make it as pretty
as you want.
I also simplified access management. In truth, this is only to reduce log data
inside the mikrotik, so if you've got ssh keys on your users, it'll still be
fruitless for a hacker to find this web page and add their IP. If anything,
you could keep the simplified login as a fake front, and re-write the script
to blacklist traffic from any sucker that adds his IP using this page. That'll
show 'em.
You'll need the mikrotik api client file https://raw.githubusercontent.com/BenMenking/routeros-api/master/routeros_api.class.php
There may be a more efficient way to do the javascript timer, but this was the
quickest way I could find to meet my needs.
*/
?>
<html>
<head>
<script>
function addCountdown(totalSeconds, elementId) {
// Set the time we're counting down from
var distance = totalSeconds;
// Update the count down every 1 second
var x = setInterval(function() {
// Find the distance between now an the count down date
distance = distance - 1000;
// Time calculations for days, hours, minutes and seconds
//var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById(elementId).innerHTML = /*days + "d " +*/ hours + "h "
+ minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById(elementId).innerHTML = "EXPIRED";
}
}, 1000);
}
</script>
</head>
<body>
<?php
function getRealIpAddr() {
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
// a little redundant i know... I was lazy and just used a quite cure-all I found online
$my_ip = getRealIpAddr();
if(isset($_REQUEST['access'])) {
$add_button = "Add my IP";
echo '<br />These IP\'s are allowed to access the router\'s ssh through 96.72.101.129 port 22.<br />note: ssh access still requires a public key assigned to a user<br />';
require_once('./routeros_api.class.php');
$API = new RouterosAPI();
$API->debug = false;
//Make a custom user and group on the mikrotik for api. Then also only allow the user to be used from the webservers ip, if possible.
if ($API->connect('192.168.1.1', 'api', 'password')) {
/// --- Add / Enable IP if requested --- ///
if(isset($_POST['whitelist'])) {
//echo "POSTED";
$ARRAY = $API->comm("/ip/firewall/address-list/print", array(
".proplist" => ".id",
"?list" => "ssh_whitelist",
"?address" => "$my_ip",
));
echo "<!--";
print_r($ARRAY);
echo "-->";
if(isset($ARRAY[0])) {
$API->comm("/ip/firewall/address-list/set", array(
".id" => $ARRAY[0][".id"],
"disabled" => "false",
"timeout" => "1d 00:00:00",
));
} else {
$API->comm("/ip/firewall/address-list/add", array(
"list" => "ssh_whitelist",
"address" => "$my_ip",
"timeout" => "1d 00:00:00",
));
}
}
/// --- End of Post Processing --- ///
/// --- Show list of whitelisted IPs --- ///
$ARRAY = $API->comm('/ip/firewall/address-list/print', array(
".proplist" => ".id,address,disabled,timeout",
"?list" => "ssh_whitelist",
));
if(isset($ARRAY[0])) {
foreach($ARRAY as $value) {
if( $value['address'] == $my_ip ) {
//users IP is already in the list
echo "<font style=\"color: green;\">You -> address ".$value['address']." added ".$value['creation-time'];
if( $value['disabled'] == "true" ) {
echo " <font color=red>DISABLED</font>";
$add_button = "Enable my IP";
} else {
$found_working_ip = true;
$add_button = "Reset my Time";
}
} else {
echo "<font>address ".$value['address'];
}
//display timeout if there is one
if(isset( $value['timeout'] )) {
//using hash of the id, because mikrotik sometimes put's symbols here that break javascript otherwise
echo " timeout: <font id=\"c".md5($value['.id'])."\">".$value['timeout']."</font>";
$str_time = preg_replace("/[s]/", "", $value['timeout']);
$str_time = preg_replace("/[a-z]/", ":", $str_time);
$str_time = preg_replace("/^([\d]{1,2})\:([\d]{2})$/", "00:$1:$2", $str_time);
sscanf($str_time, "%d:%d:%d", $hours, $minutes, $seconds);
$str_time = $hours * 3600 + $minutes * 60 + $seconds;
echo '<script>addCountdown('.$str_time.'000, "c'.md5($value['.id']).'");</script>';
}
echo "</font><br />";
$found_some = true;
}
}
if(!isset($found_some)) {
echo 'No IP\'s in whitelist<br />';
}
echo "<!--";
//print_r($ARRAY);
echo "-->";
$API->disconnect();
}
echo '<form action="?access" method="post" id="lister">';
echo 'Your IP: <input type="text" size="15" disabled value="'.$my_ip.'" /><br />';
echo '<button name="whitelist_add" onClick="document.getElementById(\'lister\').submit();">'.$add_button.'</button><br />';
//-- not necessary for my uses. But can be enabled with a little know-how
//echo '<button name="whitelist_del" onClick="document.getElementById(\'lister\').submit();">remove</button>';
echo '</form>';
} else {
echo '403<br />';
echo 'You do not have access to this resource.';
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment