1
This commit is contained in:
commit
747122e19c
88
generate_ipsec_config.php
Normal file
88
generate_ipsec_config.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
// Function to validate IP address
|
||||
function isValidIpAddress($ip) {
|
||||
return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false;
|
||||
}
|
||||
|
||||
// Function to validate CIDR notation
|
||||
function isValidCidr($cidr) {
|
||||
$parts = explode('/', $cidr);
|
||||
if (count($parts) !== 2) {
|
||||
return false; // Invalid format
|
||||
}
|
||||
|
||||
$ip = $parts[0];
|
||||
$netmask = $parts[1];
|
||||
|
||||
return isValidIpAddress($ip) && ($netmask >= 0 && $netmask <= 32);
|
||||
}
|
||||
|
||||
// Phase 1 data (with validation)
|
||||
$errors = [];
|
||||
$phase1ProfileName = $_POST["phase1_profile_name"];
|
||||
if (empty($phase1ProfileName)) { $errors[] = "Phase 1 profile name is required."; }
|
||||
|
||||
$remoteGateway = $_POST["phase1_remote_gateway"];
|
||||
if (!isValidIpAddress($remoteGateway)) { $errors[] = "Invalid remote gateway IP address."; }
|
||||
|
||||
$localAddress = $_POST["phase1_local_address"];
|
||||
if (!empty($localAddress) && !isValidIpAddress($localAddress)) { // Check only if not empty
|
||||
$errors[] = "Invalid local address (must be a single IP).";
|
||||
}
|
||||
|
||||
$ikeVersion = $_POST["phase1_ike_version"];
|
||||
$authMethod = $_POST["phase1_auth_method"];
|
||||
$preSharedKey = $authMethod === 'psk' ? $_POST["phase1_pre_shared_key"] : null;
|
||||
if ($authMethod === 'psk' && empty($preSharedKey)) { $errors[] = "Pre-shared key is required for PSK authentication."; }
|
||||
$encryptionAlgorithms = implode(",", $_POST["phase1_encryption_algorithm"]);
|
||||
$hashAlgorithms = implode(",", $_POST["phase1_hash_algorithm"]);
|
||||
$dhGroup = $_POST["phase1_dh_group"]; // Single DH group for Phase 1
|
||||
$dhGroupText = implode(",", $_POST["phase1_dh_group"]);
|
||||
$phase1Lifetime = $_POST["phase1_lifetime"];
|
||||
$remoteId = $_POST["phase1_remote_id"];
|
||||
|
||||
// Phase 2 data (with validation)
|
||||
$phase2ProfileName = $_POST["phase2_profile_name"];
|
||||
if (empty($phase2ProfileName)) { $errors[] = "Phase 2 profile name is required."; }
|
||||
|
||||
$phase2EncryptionAlgorithms = implode(",", $_POST["phase2_encryption_algorithm"]);
|
||||
$phase2HashAlgorithms = implode(",", $_POST["phase2_hash_algorithm"]);
|
||||
$pfsGroup = $_POST["phase2_pfs_group"]; // Single PFS group for Phase 2
|
||||
$phase2Lifetime = $_POST["phase2_lifetime"];
|
||||
$phase2LocalAddress = $_POST["phase2_local_address"];
|
||||
# if (!isValidCidr($phase2LocalAddress)) { $errors[] = "Invalid phase 2 local address or subnet."; }
|
||||
$remoteAddress = $_POST["phase2_remote_address"];
|
||||
# if (!isValidCidr($remoteAddress)) { $errors[] = "Invalid phase 2 remote address or subnet."; }
|
||||
|
||||
// Handle errors
|
||||
if (!empty($errors)) {
|
||||
header('Content-Type: text/plain');
|
||||
echo "Errors:\n" . implode("\n", $errors); // Output errors as plain text
|
||||
exit;
|
||||
}
|
||||
|
||||
// Generate MikroTik CLI configuration commands
|
||||
$config = "";
|
||||
|
||||
// Phase 1
|
||||
$config .= "/ip ipsec profile\nadd name=\"$phase1ProfileName\" dh-group=\"$dhGroupText\" enc-algorithm=\"$encryptionAlgorithms\" hash-algorithm=\"$hashAlgorithms\" nat-traversal=no\n\n";
|
||||
$config .= "/ip ipsec peer\nadd address=$remoteGateway";
|
||||
if (!empty($localAddress) && isValidIpAddress($localAddress)) {
|
||||
$config .= " local-address=$localAddress";
|
||||
}
|
||||
$config .= " disabled=yes name=$phase1ProfileName passive=yes profile=$phase1ProfileName\n\n";
|
||||
|
||||
// Move pre-shared key to /ip ipsec identity
|
||||
$config .= "/ip ipsec identity\nadd peer=$phase1ProfileName secret=\"$preSharedKey\"\n\n";
|
||||
|
||||
// Phase 2
|
||||
$config .= "/ip ipsec proposal\nadd name=\"$phase2ProfileName\" auth-algorithms=\"$phase2HashAlgorithms\" enc-algorithms=\"$phase2EncryptionAlgorithms\" pfs-group=$pfsGroup\n\n";
|
||||
|
||||
$config .= "/ip ipsec policy\nadd disabled=yes dst-address=$remoteAddress peer=$phase1ProfileName proposal=$phase2ProfileName src-address=$phase2LocalAddress tunnel=yes\n\n";
|
||||
|
||||
// Output configuration as plain text without download
|
||||
header('Content-Type: text/plain');
|
||||
echo $config;
|
||||
}
|
||||
?>
|
90
generate_ipsec_config.rb
Executable file
90
generate_ipsec_config.rb
Executable file
@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'cgi'
|
||||
require 'ipaddr' # Load the IPAddr library
|
||||
|
||||
cgi = CGI.new
|
||||
params = cgi.params
|
||||
|
||||
errors = []
|
||||
|
||||
# Phase 1 data (with validation)
|
||||
phase1_profile_name = params['phase1_profile_name'][0]
|
||||
errors << "Phase 1 profile name is required." if phase1_profile_name.nil? || phase1_profile_name.empty?
|
||||
|
||||
remote_gateway = params['phase1_remote_gateway'][0]
|
||||
begin
|
||||
IPAddr.new(remote_gateway)
|
||||
rescue IPAddr::InvalidAddressError
|
||||
errors << "Invalid remote gateway IP address."
|
||||
end
|
||||
|
||||
local_address = params['phase1_local_address'][0] || '' # Optional
|
||||
if !local_address.empty?
|
||||
begin
|
||||
IPAddr.new(local_address) # Check if it's a valid IP address
|
||||
errors << "Invalid local address (must be a single IP)." if IPAddr.new(local_address).prefix != 32
|
||||
rescue IPAddr::InvalidAddressError
|
||||
errors << "Invalid local address."
|
||||
end
|
||||
end
|
||||
|
||||
ike_version = params['phase1_ike_version'][0]
|
||||
auth_method = params['phase1_auth_method'][0]
|
||||
pre_shared_key = (auth_method == 'psk') ? params['phase1_pre_shared_key'][0] : nil
|
||||
errors << "Pre-shared key is required for PSK authentication." if auth_method == 'psk' && (pre_shared_key.nil? || pre_shared_key.empty?)
|
||||
encryption_algorithms = params['phase1_encryption_algorithm'] || []
|
||||
hash_algorithms = params['phase1_hash_algorithm'] || []
|
||||
dh_group = params['phase1_dh_group'][0]
|
||||
phase1_lifetime = params['phase1_lifetime'][0]
|
||||
remote_id = params['phase1_remote_id'][0] || '' # Optional
|
||||
|
||||
# Phase 2 data (with validation)
|
||||
phase2_profile_name = params['phase2_profile_name'][0]
|
||||
errors << "Phase 2 profile name is required." if phase2_profile_name.nil? || phase2_profile_name.empty?
|
||||
phase2_encryption_algorithms = params['phase2_encryption_algorithm'] || []
|
||||
phase2_hash_algorithms = params['phase2_hash_algorithm'] || []
|
||||
pfs_group = params['phase2_pfs_group'][0] || ''
|
||||
phase2_lifetime = params['phase2_lifetime'][0]
|
||||
phase2_local_address = params['phase2_local_address'][0]
|
||||
begin
|
||||
IPAddr.new(phase2_local_address) # Check if it's a valid IP address or CIDR
|
||||
rescue IPAddr::InvalidAddressError
|
||||
errors << "Invalid phase 2 local address or subnet."
|
||||
end
|
||||
|
||||
remote_address = params['phase2_remote_address'][0]
|
||||
begin
|
||||
IPAddr.new(remote_address) # Check if it's a valid IP address or CIDR
|
||||
rescue IPAddr::InvalidAddressError
|
||||
errors << "Invalid phase 2 remote address or subnet."
|
||||
end
|
||||
|
||||
|
||||
# Handle errors
|
||||
if errors.any?
|
||||
cgi.header('type' => 'text/plain')
|
||||
puts "Errors:\n#{errors.join("\n")}"
|
||||
exit
|
||||
end
|
||||
|
||||
# Generate MikroTik CLI configuration commands
|
||||
config = ""
|
||||
|
||||
# Phase 1
|
||||
config << "/ip ipsec profile\nadd name=\"#{phase1_profile_name}\" dh-group=#{dh_group} enc-algorithm=\"#{encryption_algorithms.join(',')}\" hash-algorithm=\"#{hash_algorithms.join(',')}\" nat-traversal=no\n\n"
|
||||
config << "/ip ipsec peer\nadd address=#{remote_gateway} "
|
||||
config << "local-address=#{local_address} " unless local_address.empty?
|
||||
config << "disabled=yes name=#{phase1_profile_name} passive=yes profile=#{phase1_profile_name}\n\n"
|
||||
|
||||
# Move pre-shared key to /ip ipsec identity
|
||||
config << "/ip ipsec identity\nadd peer=#{phase1_profile_name} secret=\"#{pre_shared_key}\"\n\n"
|
||||
|
||||
# Phase 2
|
||||
config << "/ip ipsec proposal\nadd name=\"#{phase2_profile_name}\" auth-algorithms=\"#{phase2_hash_algorithms.join(',')}\" enc-algorithms=\"#{phase2_encryption_algorithms.join(',')}\" pfs-group=#{pfs_group}\n\n"
|
||||
config << "/ip ipsec policy\nadd disabled=yes dst-address=#{remote_address} peer=#{phase1_profile_name} proposal=#{phase2_profile_name} src-address=#{phase2_local_address} tunnel=yes\n\n"
|
||||
|
||||
# Output configuration as plain text without download
|
||||
cgi.header('type' => 'text/plain')
|
||||
puts
|
||||
puts config
|
117
index.html
Normal file
117
index.html
Normal file
@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>MikroTik IPsec Configuration</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>MikroTik IPsec Configuration</h1>
|
||||
<form action="generate_ipsec_config.rb" method="post" autocomplete="off">
|
||||
<fieldset>
|
||||
<legend>Phase 1</legend>
|
||||
|
||||
<label for="phase1-profile-name">Profile Name:</label>
|
||||
<input type="text" id="phase1-profile-name" name="phase1_profile_name" autocomplete="new-password" required><br><br>
|
||||
|
||||
<label for="phase1-remote-gateway">Remote Gateway (IP Address):</label>
|
||||
<input type="text" id="phase1-remote-gateway" name="phase1_remote_gateway" autocomplete="new-password" required><br><br>
|
||||
|
||||
<label for="phase1-local-address">Local Address (Single IP, optional):</label>
|
||||
<input type="text" id="phase1-local-address" name="phase1_local_address" autocomplete="new-password"><br><br>
|
||||
|
||||
<label for="phase1-ike-version">IKE Version:</label>
|
||||
<select id="phase1-ike-version" name="phase1_ike_version" autocomplete="new-password" required>
|
||||
<option value="ike2" selected>IKEv2</option>
|
||||
<option value="ike1">IKEv1</option>
|
||||
</select><br><br>
|
||||
|
||||
<label for="phase1-auth-method">Authentication Method:</label>
|
||||
<select id="phase1-auth-method" name="phase1_auth_method" autocomplete="new-password" required>
|
||||
<option value="psk" selected>Pre-shared Key</option>
|
||||
<option value="rsa">RSA Signatures</option>
|
||||
</select><br><br>
|
||||
|
||||
<label for="phase1-pre-shared-key">Pre-shared Key:</label>
|
||||
<input type="password" id="phase1-pre-shared-key" name="phase1_pre_shared_key" autocomplete="new-password" required><br><br>
|
||||
|
||||
<label for="phase1-encryption-algorithm">Encryption Algorithms (multiple allowed):</label>
|
||||
<select id="phase1-encryption-algorithm" name="phase1_encryption_algorithm[]" multiple autocomplete="new-password" required>
|
||||
<option value="aes-128" selected>AES-128</option>
|
||||
<option value="aes-192">AES-192</option>
|
||||
<option value="aes-256">AES-256</option>
|
||||
</select><br><br>
|
||||
|
||||
<label for="phase1-hash-algorithm">Hash Algorithms (multiple allowed):</label>
|
||||
<select id="phase1-hash-algorithm" name="phase1_hash_algorithm[]" multiple autocomplete="new-password" required>
|
||||
<option value="sha1">SHA1</option>
|
||||
<option value="sha256" selected>SHA256</option>
|
||||
<option value="sha384">SHA384</option>
|
||||
<option value="sha512">SHA512</option>
|
||||
</select><br><br>
|
||||
|
||||
<label for="phase1-dh-group">DH Groups (multiple allowed):</label>
|
||||
<select id="phase1-dh-group" name="phase1_dh_group[]" multiple autocomplete="new-password" required>
|
||||
<option value="modp1024">Group 2</option>
|
||||
<option value="modp1536" selected>Group 14</option>
|
||||
<option value="modp2048" selected>Group 15</option>
|
||||
<option value="modp3072">Group 16</option>
|
||||
<option value="modp4096">Group 17</option>
|
||||
<option value="modp6144">Group 18</option>
|
||||
<option value="modp8192">Group 19</option>
|
||||
</select><br><br>
|
||||
|
||||
<label for="phase1-remote-id">Remote ID (optional):</label>
|
||||
<input type="text" id="phase1-remote-id" name="phase1_remote_id" autocomplete="new-password"><br><br>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Phase 2</legend>
|
||||
<label for="phase2-profile-name">Profile Name:</label>
|
||||
<input type="text" id="phase2-profile-name" name="phase2_profile_name" autocomplete="new-password" required><br><br>
|
||||
|
||||
<label for="phase2-local-address">Local Address (or Subnet):</label>
|
||||
<input type="text" id="phase2-local-address" name="phase2_local_address" placeholder="e.g., 192.168.1.0/24" autocomplete="new-password" required><br><br>
|
||||
|
||||
<label for="phase2-remote-address">Remote Address (or Subnet):</label>
|
||||
<input type="text" id="phase2-remote-address" name="phase2_remote_address" placeholder="e.g., 10.0.0.0/24" autocomplete="new-password" required><br><br>
|
||||
|
||||
<label for="phase2-encryption-algorithm">Encryption Algorithms (multiple allowed):</label>
|
||||
<select id="phase2-encryption-algorithm" name="phase2_encryption_algorithm[]" multiple autocomplete="new-password" required>
|
||||
<option value="aes-128-cbc" selected>aes-128-cbc</option>
|
||||
<option value="aes-128-ctr" selected>aes-128-ctr</option>
|
||||
<option value="aes-128-gcm" selected>aes-128-gcm</option>
|
||||
<option value="aes-192-cbc" selected>aes-192-cbc</option>
|
||||
<option value="aes-256-cbc" selected>aes-256-cbc</option>
|
||||
<option value="aes-256-ctr" selected>aes-256-ctr</option>
|
||||
<option value="aes-256-gcm" selected>aes-256-gcm</option>
|
||||
</select><br><br>
|
||||
|
||||
<label for="phase2-hash-algorithm">Hash Algorithms (multiple allowed):</label>
|
||||
<select id="phase2-hash-algorithm" name="phase2_hash_algorithm[]" multiple autocomplete="new-password" required>
|
||||
<option value="sha1" selected>SHA1</option>
|
||||
<option value="sha256" selected>SHA256</option>
|
||||
<option value="sha384">SHA384</option>
|
||||
<option value="sha512">SHA512</option>
|
||||
</select><br><br>
|
||||
|
||||
<label for="phase2-pfs-group">PFS Group:</label>
|
||||
<select id="phase2-pfs-group" name="phase2_pfs_group" autocomplete="new-password" required>
|
||||
<option value="modp1536">Group 14</option>
|
||||
<option value="modp2048" selected>Group 15</option>
|
||||
<option value="modp3072">Group 16</option>
|
||||
<option value="modp4096">Group 17</option>
|
||||
<option value="modp6144">Group 18</option>
|
||||
<option value="modp8192">Group 19</option>
|
||||
</select><br><br>
|
||||
<label for="phase2-lifetime">Lifetime (seconds):</label>
|
||||
<input type="number" id="phase2-lifetime" name="phase2_lifetime" value="43200" min="1" autocomplete="new-password" required><br><br>
|
||||
</fieldset>
|
||||
|
||||
<input type="submit" value="Generate Configuration">
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
94
style.css
Normal file
94
style.css
Normal file
@ -0,0 +1,94 @@
|
||||
/* Basic Styling */
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Modern, readable font */
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #f4f4f4; /* Light background */
|
||||
color: #333; /* Dark text for contrast */
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 20px auto;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #ddd;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
legend {
|
||||
font-weight: bold;
|
||||
padding: 0 10px; /* Add some padding around the legend text */
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: 600; /* Slightly bolder labels */
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="number"],
|
||||
select {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin-bottom: 15px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
select {
|
||||
height: 45px; /* Consistent height for selects */
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
background-color: #007bff; /* Blue button */
|
||||
color: white;
|
||||
padding: 12px 20px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
transition: background-color 0.3s; /* Smooth transition on hover */
|
||||
}
|
||||
|
||||
input[type="submit"]:hover {
|
||||
background-color: #0056b3; /* Darker blue on hover */
|
||||
}
|
||||
|
||||
/* Responsive Styles */
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
max-width: 95%;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="number"],
|
||||
select {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
fieldset {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
}
|
12
test-1.sh
Executable file
12
test-1.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# 'https://www.ngtech.co.il/ipracticom/ipsec/2/generate_ipsec_config.rb'
|
||||
URL="$1"
|
||||
|
||||
curl "${URL}" \
|
||||
-H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
|
||||
-H 'content-type: application/x-www-form-urlencoded' \
|
||||
-H 'origin: https://www.ngtech.co.il' \
|
||||
-H 'priority: u=0, i' \
|
||||
-H 'referer: https://www.ngtech.co.il/ipracticom/ipsec/2/' \
|
||||
--data-raw 'phase1_profile_name=test2-p1&phase1_remote_gateway=1.1.1.1&phase1_local_address=&phase1_ike_version=ike2&phase1_auth_method=psk&phase1_pre_shared_key=Test123&phase1_encryption_algorithm%5B%5D=aes-128&phase1_hash_algorithm%5B%5D=sha256&phase1_dh_group%5B%5D=modp1536&phase1_dh_group%5B%5D=modp2048&phase1_remote_id=&phase2_profile_name=test2-ph2&phase2_local_address=192.168.0.0%2F24&phase2_remote_address=192.168.1.0%2F24&phase2_encryption_algorithm%5B%5D=aes-128-cbc&phase2_encryption_algorithm%5B%5D=aes-128-ctr&phase2_encryption_algorithm%5B%5D=aes-128-gcm&phase2_encryption_algorithm%5B%5D=aes-192-cbc&phase2_encryption_algorithm%5B%5D=aes-256-cbc&phase2_encryption_algorithm%5B%5D=aes-256-ctr&phase2_encryption_algorithm%5B%5D=aes-256-gcm&phase2_hash_algorithm%5B%5D=sha1&phase2_hash_algorithm%5B%5D=sha256&phase2_pfs_group=modp2048&phase2_lifetime=43200'
|
Loading…
Reference in New Issue
Block a user