Files
Juniper/juniper_initial_config_generator.html
T

523 lines
28 KiB
HTML

<h2 class="sr-only">Initial Juniper Configuration Generator</h2>
<style>
*{box-sizing:border-box;margin:0;padding:0}
.app{padding:1.5rem 0;max-width:680px}
.header{margin-bottom:1.5rem}
.header h1{font-size:18px;font-weight:500;color:var(--color-text-primary);font-family:var(--font-sans);display:flex;align-items:center;gap:8px}
.header p{font-size:13px;color:var(--color-text-secondary);margin-top:4px;font-family:var(--font-sans)}
.tabs{display:flex;gap:2px;border-bottom:0.5px solid var(--color-border-tertiary);margin-bottom:1.5rem}
.tab{padding:8px 14px;font-size:13px;font-family:var(--font-sans);color:var(--color-text-secondary);cursor:pointer;border:none;background:none;border-bottom:2px solid transparent;margin-bottom:-0.5px;transition:color .15s}
.tab:hover{color:var(--color-text-primary)}
.tab.active{color:var(--color-text-primary);border-bottom-color:var(--color-text-primary);font-weight:500}
.section{display:none}.section.active{display:block}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:1.5rem}
.field{display:flex;flex-direction:column;gap:4px}
.field label{font-size:12px;font-family:var(--font-sans);color:var(--color-text-secondary);text-transform:uppercase;letter-spacing:.04em}
.field input,.field select{font-family:var(--font-mono);font-size:13px;padding:8px 10px;border:0.5px solid var(--color-border-secondary);border-radius:var(--border-radius-md);background:var(--color-background-primary);color:var(--color-text-primary);width:100%}
.field input:focus,.field select:focus{outline:none;border-color:var(--color-border-primary)}
.slabel{font-size:11px;font-family:var(--font-sans);font-weight:500;text-transform:uppercase;letter-spacing:.06em;color:var(--color-text-tertiary);margin-bottom:10px;margin-top:1.5rem;border-bottom:0.5px solid var(--color-border-tertiary);padding-bottom:6px}
.slabel:first-child{margin-top:0}
.iface-row{display:grid;grid-template-columns:1fr 1fr 1fr 32px;gap:8px;align-items:end;margin-bottom:8px}
.iface-row .field,.vlan-row .field,.bgp-row .field,.static-row .field{margin:0}
.vlan-row{display:grid;grid-template-columns:1fr 70px 1fr 32px;gap:8px;align-items:end;margin-bottom:8px}
.bgp-row{display:grid;grid-template-columns:1fr 1fr 1fr 32px;gap:8px;align-items:end;margin-bottom:8px}
.static-row{display:grid;grid-template-columns:1fr 1fr 1fr 32px;gap:8px;align-items:end;margin-bottom:8px}
.rm{height:36px;width:32px;border:0.5px solid var(--color-border-secondary);background:none;border-radius:var(--border-radius-md);cursor:pointer;color:var(--color-text-tertiary);font-size:16px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.rm:hover{background:var(--color-background-danger);color:var(--color-text-danger);border-color:var(--color-border-danger)}
.add-btn{font-size:12px;font-family:var(--font-sans);color:var(--color-text-secondary);background:none;border:0.5px dashed var(--color-border-secondary);border-radius:var(--border-radius-md);padding:6px 12px;cursor:pointer;margin-top:4px}
.add-btn:hover{color:var(--color-text-primary);border-color:var(--color-border-primary)}
.gen-btn{width:100%;padding:10px;font-size:14px;font-family:var(--font-sans);font-weight:500;background:var(--color-text-primary);color:var(--color-background-primary);border:none;border-radius:var(--border-radius-md);cursor:pointer;margin-top:1rem;display:flex;align-items:center;justify-content:center;gap:8px;transition:opacity .15s}
.gen-btn:hover{opacity:.85}
.out-area{margin-top:1.5rem}
.out-hdr{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.out-title{font-size:12px;font-family:var(--font-sans);font-weight:500;text-transform:uppercase;letter-spacing:.06em;color:var(--color-text-secondary)}
.copy-btn{font-size:12px;font-family:var(--font-sans);color:var(--color-text-secondary);background:none;border:0.5px solid var(--color-border-secondary);border-radius:var(--border-radius-md);padding:4px 10px;cursor:pointer;display:flex;align-items:center;gap:5px}
.copy-btn:hover{color:var(--color-text-primary);border-color:var(--color-border-primary)}
.cfg{background:var(--color-background-secondary);border:0.5px solid var(--color-border-tertiary);border-radius:var(--border-radius-md);padding:1rem;font-size:12px;font-family:var(--font-mono);color:var(--color-text-primary);line-height:1.7;white-space:pre;overflow:auto;min-height:120px;max-height:540px}
.cfg .comment{color:var(--color-text-tertiary)}
.cfg .key{color:var(--color-text-info)}
.cbrow{display:flex;align-items:center;gap:8px;padding:5px 0}
.cbrow input[type=checkbox]{width:16px;height:16px;accent-color:var(--color-text-primary)}
.cbrow label{font-size:13px;font-family:var(--font-sans);color:var(--color-text-primary);cursor:pointer}
.badge{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-family:var(--font-sans);padding:2px 8px;border-radius:var(--border-radius-md);background:var(--color-background-success);color:var(--color-text-success);margin-left:8px}
</style>
<div class="app">
<div class="header">
<h1><i class="ti ti-router" aria-hidden="true"></i> Juniper Config Generator <span class="badge"><i class="ti ti-wifi-off" aria-hidden="true"></i> offline</span></h1>
<p>Rules-based JunOS set-format config — no network required</p>
</div>
<div class="tabs">
<button class="tab active" onclick="switchTab(this,'device')">Device</button>
<button class="tab" onclick="switchTab(this,'interfaces')">Interfaces</button>
<button class="tab" onclick="switchTab(this,'vlans')">VLANs</button>
<button class="tab" onclick="switchTab(this,'routing')">Routing</button>
<button class="tab" onclick="switchTab(this,'security')">Security</button>
</div>
<div id="tab-device" class="section active">
<div class="slabel">Device Identity</div>
<div class="form-grid">
<div class="field"><label>Hostname</label><input id="hostname" placeholder="router-01"/></div>
<div class="field"><label>Domain Name</label><input id="domain" placeholder="example.com"/></div>
<div class="field"><label>Device Type</label>
<select id="device_type">
<option value="mx">MX Series (Core/Edge)</option>
<option value="ex">EX Series (Switching)</option>
<option value="srx">SRX Series (Security)</option>
<option value="qfx">QFX Series (Data Center)</option>
<option value="ptx">PTX Series (Packet Transport)</option>
</select>
</div>
<div class="field"><label>JunOS Version</label>
<select id="junos_ver"><option>21.4R3</option><option>22.2R1</option><option>22.4R2</option><option>23.2R1</option><option selected>23.4R1</option></select>
</div>
</div>
<div class="slabel">Management</div>
<div class="form-grid">
<div class="field"><label>Mgmt Interface</label>
<select id="mgmt_iface"><option value="fxp0">fxp0 (MX/SRX)</option><option value="me0">me0 (EX/QFX)</option><option value="em0">em0 (vSRX)</option></select>
</div>
<div class="field"><label>Mgmt IP / Prefix</label><input id="mgmt_ip" placeholder="192.168.1.1/24"/></div>
<div class="field"><label>Default Gateway</label><input id="mgmt_gw" placeholder="192.168.1.254"/></div>
<div class="field"><label>Timezone</label>
<select id="tz"><option>America/New_York</option><option>America/Chicago</option><option>America/Denver</option><option>America/Los_Angeles</option><option>Europe/London</option><option>Europe/Amsterdam</option><option>Asia/Tokyo</option><option>UTC</option></select>
</div>
<div class="field"><label>NTP Server</label><input id="ntp" placeholder="pool.ntp.org"/></div>
<div class="field"><label>DNS Server</label><input id="dns" placeholder="8.8.8.8"/></div>
</div>
<div class="slabel">Authentication</div>
<div class="form-grid">
<div class="field"><label>Root Encrypted Password</label><input id="root_pw" placeholder='$6$abc123... (or leave blank)'/>
</div>
<div class="field"><label>Admin Username</label><input id="admin_user" placeholder="netadmin"/></div>
<div class="field"><label>TACACS+ Server</label><input id="tacacs" placeholder="10.0.0.100 (optional)"/></div>
<div class="field"><label>RADIUS Server</label><input id="radius" placeholder="10.0.0.101 (optional)"/></div>
</div>
</div>
<div id="tab-interfaces" class="section">
<div class="slabel">Physical Interfaces</div>
<div id="iface-list"></div>
<button class="add-btn" onclick="addIface()"><i class="ti ti-plus" aria-hidden="true"></i> Add interface</button>
</div>
<div id="tab-vlans" class="section">
<div class="slabel">VLAN Definitions</div>
<div id="vlan-list"></div>
<button class="add-btn" onclick="addVlan()"><i class="ti ti-plus" aria-hidden="true"></i> Add VLAN</button>
</div>
<div id="tab-routing" class="section">
<div class="slabel">Static Routes</div>
<div id="static-list"></div>
<button class="add-btn" onclick="addStatic()"><i class="ti ti-plus" aria-hidden="true"></i> Add static route</button>
<div class="slabel">OSPF</div>
<div class="form-grid">
<div class="field"><label>Enable OSPF</label>
<select id="ospf_enable"><option value="">Disabled</option><option value="ospf">OSPFv2</option><option value="ospf3">OSPFv3</option></select>
</div>
<div class="field"><label>Router ID</label><input id="router_id" placeholder="1.1.1.1"/></div>
<div class="field"><label>Area</label><input id="ospf_area" placeholder="0.0.0.0"/></div>
<div class="field"><label>OSPF Interfaces (comma-sep)</label><input id="ospf_ifaces" placeholder="ge-0/0/0, ge-0/0/1"/></div>
</div>
<div class="slabel">BGP</div>
<div class="form-grid">
<div class="field"><label>Local AS</label><input id="local_as" placeholder="65001"/></div>
<div class="field"><label>Router ID (BGP)</label><input id="bgp_rid" placeholder="1.1.1.1"/></div>
</div>
<div id="bgp-list"></div>
<button class="add-btn" onclick="addBgp()"><i class="ti ti-plus" aria-hidden="true"></i> Add BGP neighbor</button>
</div>
<div id="tab-security" class="section">
<div class="slabel">Firewall Filter — loopback protection</div>
<div class="cbrow"><input type="checkbox" id="fw_ssh" checked><label for="fw_ssh">Allow SSH</label></div>
<div class="cbrow"><input type="checkbox" id="fw_icmp" checked><label for="fw_icmp">Allow ICMP</label></div>
<div class="cbrow"><input type="checkbox" id="fw_bgp"><label for="fw_bgp">Allow BGP (TCP 179)</label></div>
<div class="cbrow"><input type="checkbox" id="fw_ospf"><label for="fw_ospf">Allow OSPF multicast</label></div>
<div class="cbrow"><input type="checkbox" id="fw_snmp"><label for="fw_snmp">Allow SNMP</label></div>
<div class="cbrow"><input type="checkbox" id="fw_enable" checked><label for="fw_enable">Apply filter to loopback (lo0)</label></div>
<div class="slabel">SNMP</div>
<div class="form-grid">
<div class="field"><label>SNMP Community</label><input id="snmp_community" placeholder="public"/></div>
<div class="field"><label>SNMP Client Prefix</label><input id="snmp_clients" placeholder="10.0.0.0/24"/></div>
</div>
<div class="slabel">Syslog</div>
<div class="form-grid">
<div class="field"><label>Syslog Server</label><input id="syslog" placeholder="10.0.0.200"/></div>
<div class="field"><label>Syslog Facility</label>
<select id="syslog_facility"><option>any</option><option>authorization</option><option>daemon</option><option>kernel</option></select>
</div>
</div>
<div class="slabel">SRX Security (SRX only)</div>
<div class="cbrow"><input type="checkbox" id="srx_zones"><label for="srx_zones">Generate trust / untrust zones</label></div>
<div class="cbrow"><input type="checkbox" id="srx_nat"><label for="srx_nat">Source NAT trust → untrust</label></div>
<div class="form-grid" style="margin-top:10px">
<div class="field"><label>Trust Interface</label><input id="srx_trust_if" placeholder="ge-0/0/1"/></div>
<div class="field"><label>Untrust Interface</label><input id="srx_untrust_if" placeholder="ge-0/0/0"/></div>
</div>
</div>
<button class="gen-btn" onclick="generate()"><i class="ti ti-code" aria-hidden="true"></i> Generate Configuration</button>
<div class="out-area" id="out-area" style="display:none">
<div class="out-hdr">
<span class="out-title">JunOS Configuration</span>
<button class="copy-btn" id="copy-btn" onclick="copyConfig()"><i class="ti ti-copy" aria-hidden="true"></i> Copy</button>
</div>
<div class="cfg" id="cfg-out"></div>
</div>
</div>
<script>
let ifaces=[], vlans=[], statics=[], bgps=[];
const v=id=>{const e=document.getElementById(id);return e?e.value.trim():''};
const cb=id=>{const e=document.getElementById(id);return e&&e.checked};
function switchTab(el,name){
document.querySelectorAll('.tab').forEach(t=>t.classList.remove('active'));
document.querySelectorAll('.section').forEach(s=>s.classList.remove('active'));
el.classList.add('active');
document.getElementById('tab-'+name).classList.add('active');
}
function addIface(){
const id=Date.now();ifaces.push(id);
const r=document.createElement('div');r.className='iface-row';r.id='if-'+id;
r.innerHTML=`<div class="field"><label>Interface</label><input id="ifn${id}" placeholder="ge-0/0/0"/></div>
<div class="field"><label>IP/Prefix</label><input id="ifi${id}" placeholder="10.0.0.1/30"/></div>
<div class="field"><label>Description</label><input id="ifd${id}" placeholder="uplink"/></div>
<button class="rm" onclick="rmRow('if',${id})"><i class="ti ti-x" aria-hidden="true"></i></button>`;
document.getElementById('iface-list').appendChild(r);
}
function addVlan(){
const id=Date.now();vlans.push(id);
const r=document.createElement('div');r.className='vlan-row';r.id='vl-'+id;
r.innerHTML=`<div class="field"><label>Name</label><input id="vln${id}" placeholder="mgmt"/></div>
<div class="field"><label>ID</label><input type="number" id="vlid${id}" placeholder="10" min="1" max="4094"/></div>
<div class="field"><label>IRB IP/Prefix</label><input id="vlip${id}" placeholder="192.168.10.1/24"/></div>
<button class="rm" onclick="rmRow('vl',${id})"><i class="ti ti-x" aria-hidden="true"></i></button>`;
document.getElementById('vlan-list').appendChild(r);
}
function addStatic(){
const id=Date.now();statics.push(id);
const r=document.createElement('div');r.className='static-row';r.id='st-'+id;
r.innerHTML=`<div class="field"><label>Prefix</label><input id="stp${id}" placeholder="0.0.0.0/0"/></div>
<div class="field"><label>Next Hop</label><input id="stn${id}" placeholder="10.0.0.254"/></div>
<div class="field"><label>Description</label><input id="std${id}" placeholder="default-route"/></div>
<button class="rm" onclick="rmRow('st',${id})"><i class="ti ti-x" aria-hidden="true"></i></button>`;
document.getElementById('static-list').appendChild(r);
}
function addBgp(){
const id=Date.now();bgps.push(id);
const r=document.createElement('div');r.className='bgp-row';r.id='bg-'+id;
r.innerHTML=`<div class="field"><label>Neighbor IP</label><input id="bgip${id}" placeholder="10.0.0.2"/></div>
<div class="field"><label>Remote AS</label><input id="bgas${id}" placeholder="65002"/></div>
<div class="field"><label>Description</label><input id="bgd${id}" placeholder="isp-peer"/></div>
<button class="rm" onclick="rmRow('bg',${id})"><i class="ti ti-x" aria-hidden="true"></i></button>`;
document.getElementById('bgp-list').appendChild(r);
}
function rmRow(t,id){
document.getElementById(t+'-'+id).remove();
if(t==='if')ifaces=ifaces.filter(i=>i!==id);
if(t==='vl')vlans=vlans.filter(i=>i!==id);
if(t==='st')statics=statics.filter(i=>i!==id);
if(t==='bg')bgps=bgps.filter(i=>i!==id);
}
function lines(...args){return args.filter(Boolean).join('\n')}
function section(title){return `\n## ─── ${title} ───`}
function generate(){
const out=[];
const hostname=v('hostname')||'juniper-router';
const domain=v('domain');
const dtype=v('device_type');
const mgmtIf=v('mgmt_iface');
const mgmtIp=v('mgmt_ip');
const mgmtGw=v('mgmt_gw');
const tz=v('tz');
const ntp=v('ntp');
const dns=v('dns');
const rootPw=v('root_pw');
const adminUser=v('admin_user');
const tacacs=v('tacacs');
const radius=v('radius');
out.push(`## Juniper Networks — JunOS Set Configuration`);
out.push(`## Device: ${hostname} | Type: ${v('device_type')} | Version: ${v('junos_ver')}`);
out.push(`## Generated: ${new Date().toISOString()}`);
out.push(section('SYSTEM'));
out.push(`set system host-name ${hostname}`);
if(domain) out.push(`set system domain-name ${domain}`);
out.push(`set system time-zone ${tz}`);
out.push(`set system no-redirects`);
out.push(`set system internet-options no-source-quench`);
out.push(`set system internet-options tcp-drop-synfin-set`);
out.push(`set system default-address-selection`);
if(rootPw){
out.push(`set system root-authentication encrypted-password "${rootPw}"`);
} else {
out.push(`## set system root-authentication encrypted-password "CHANGEME"`);
}
if(adminUser){
out.push(`set system login user ${adminUser} class super-user`);
out.push(`set system login user ${adminUser} authentication encrypted-password "CHANGEME"`);
}
out.push(`set system login message "\\n*** Authorized access only. All activity is logged. ***\\n"`);
out.push(`set system services ssh root-login deny`);
out.push(`set system services ssh protocol-version v2`);
out.push(`set system services ssh max-sessions-per-connection 4`);
if(mgmtIp){
const prefix=mgmtIp.split('/')[0];
out.push(`set system services ssh client-alive-count-max 3`);
}
out.push(`set system services netconf ssh`);
if(tacacs){
out.push(section('TACACS+'));
out.push(`set system tacplus-server ${tacacs} secret "CHANGEME"`);
out.push(`set system tacplus-server ${tacacs} timeout 5`);
out.push(`set system tacplus-server ${tacacs} single-connection`);
out.push(`set system authentication-order [ tacplus password ]`);
}
if(radius){
out.push(section('RADIUS'));
out.push(`set system radius-server ${radius} secret "CHANGEME"`);
out.push(`set system radius-server ${radius} timeout 5`);
out.push(`set system radius-server ${radius} retry 3`);
if(!tacacs) out.push(`set system authentication-order [ radius password ]`);
}
if(ntp){
out.push(section('NTP'));
out.push(`set system ntp server ${ntp}`);
out.push(`set system ntp source-address ${mgmtIp?mgmtIp.split('/')[0]:''}`);
}
if(dns){
out.push(section('DNS'));
out.push(`set system name-server ${dns}`);
}
out.push(section('SYSLOG'));
const syslogSrv=v('syslog');
const syslogFac=v('syslog_facility')||'any';
out.push(`set system syslog user * any emergency`);
out.push(`set system syslog file messages ${syslogFac} notice`);
out.push(`set system syslog file messages authorization info`);
out.push(`set system syslog file interactive-commands interactive-commands any`);
if(syslogSrv){
out.push(`set system syslog host ${syslogSrv} ${syslogFac} any`);
out.push(`set system syslog host ${syslogSrv} source-address ${mgmtIp?mgmtIp.split('/')[0]:''}`);
}
out.push(section('ARCHIVAL'));
out.push(`set system archival configuration transfer-on-commit`);
out.push(`set system archival configuration archive-sites "scp://netadmin@backup-server/configs/"`);
out.push(section('INTERFACES'));
if(mgmtIp){
out.push(`set interfaces ${mgmtIf} unit 0 family inet address ${mgmtIp}`);
}
const ifaceData=ifaces.map(id=>({name:v('ifn'+id),ip:v('ifi'+id),desc:v('ifd'+id)})).filter(i=>i.name);
for(const iface of ifaceData){
if(iface.desc) out.push(`set interfaces ${iface.name} description "${iface.desc}"`);
out.push(`set interfaces ${iface.name} mtu 9192`);
if(iface.ip){
out.push(`set interfaces ${iface.name} unit 0 family inet address ${iface.ip}`);
} else {
out.push(`set interfaces ${iface.name} unit 0 family inet`);
}
}
const vlanData=vlans.map(id=>({name:v('vln'+id),id:v('vlid'+id),ip:v('vlip'+id)})).filter(i=>i.name&&i.id);
if(vlanData.length){
out.push(section('VLANS'));
for(const vl of vlanData){
out.push(`set vlans ${vl.name} vlan-id ${vl.id}`);
if(vl.ip) out.push(`set vlans ${vl.name} l3-interface irb.${vl.id}`);
}
out.push('');
for(const vl of vlanData){
if(vl.ip){
out.push(`set interfaces irb unit ${vl.id} description "L3-${vl.name}"`);
out.push(`set interfaces irb unit ${vl.id} family inet address ${vl.ip}`);
}
}
}
const staticData=statics.map(id=>({prefix:v('stp'+id),nh:v('stn'+id),desc:v('std'+id)})).filter(i=>i.prefix&&i.nh);
const ospfProto=v('ospf_enable');
const routerId=v('router_id');
const localAs=v('local_as');
const bgpRid=v('bgp_rid');
const bgpData=bgps.map(id=>({ip:v('bgip'+id),as:v('bgas'+id),desc:v('bgd'+id)})).filter(i=>i.ip);
if(staticData.length||routerId||ospfProto||localAs||mgmtGw){
out.push(section('ROUTING OPTIONS'));
if(routerId||bgpRid) out.push(`set routing-options router-id ${routerId||bgpRid}`);
if(localAs) out.push(`set routing-options autonomous-system ${localAs}`);
if(mgmtGw) out.push(`set routing-options static route 0.0.0.0/0 next-hop ${mgmtGw}`);
for(const sr of staticData){
out.push(`set routing-options static route ${sr.prefix} next-hop ${sr.nh}`);
if(sr.desc) out.push(`set routing-options static route ${sr.prefix} description "${sr.desc}"`);
}
}
if(ospfProto){
const area=v('ospf_area')||'0.0.0.0';
const ospfIfaces=(v('ospf_ifaces')||'').split(',').map(s=>s.trim()).filter(Boolean);
out.push(section('OSPF'));
for(const iface of ospfIfaces){
out.push(`set protocols ${ospfProto} area ${area} interface ${iface}.0`);
}
if(ospfIfaces.length===0){
out.push(`## set protocols ${ospfProto} area ${area} interface <INTERFACE>.0`);
}
out.push(`set protocols ${ospfProto} export redistribute-connected`);
}
if(localAs&&bgpData.length){
out.push(section('BGP'));
out.push(`set protocols bgp group EBGP type external`);
for(const n of bgpData){
if(n.desc) out.push(`set protocols bgp group EBGP neighbor ${n.ip} description "${n.desc}"`);
out.push(`set protocols bgp group EBGP neighbor ${n.ip} peer-as ${n.as}`);
}
out.push(`set protocols bgp group EBGP hold-time 90`);
out.push(`set protocols bgp group EBGP keep-all`);
}
const fwSsh=cb('fw_ssh');
const fwIcmp=cb('fw_icmp');
const fwBgp=cb('fw_bgp');
const fwOspf=cb('fw_ospf');
const fwSnmp=cb('fw_snmp');
const fwEnable=cb('fw_enable');
if(fwSsh||fwIcmp||fwBgp||fwOspf||fwSnmp){
out.push(section('FIREWALL FILTER — PROTECT-RE'));
out.push(`set firewall family inet filter PROTECT-RE interface-specific`);
let term=1;
if(fwSsh){
out.push(`set firewall family inet filter PROTECT-RE term T${term}-SSH from protocol tcp`);
out.push(`set firewall family inet filter PROTECT-RE term T${term}-SSH from destination-port ssh`);
out.push(`set firewall family inet filter PROTECT-RE term T${term}-SSH then accept`);term++;
}
if(fwBgp){
out.push(`set firewall family inet filter PROTECT-RE term T${term}-BGP from protocol tcp`);
out.push(`set firewall family inet filter PROTECT-RE term T${term}-BGP from destination-port bgp`);
out.push(`set firewall family inet filter PROTECT-RE term T${term}-BGP then accept`);term++;
}
if(fwOspf){
out.push(`set firewall family inet filter PROTECT-RE term T${term}-OSPF from protocol ospf`);
out.push(`set firewall family inet filter PROTECT-RE term T${term}-OSPF then accept`);term++;
}
if(fwIcmp){
out.push(`set firewall family inet filter PROTECT-RE term T${term}-ICMP from protocol icmp`);
out.push(`set firewall family inet filter PROTECT-RE term T${term}-ICMP then accept`);term++;
}
if(fwSnmp){
out.push(`set firewall family inet filter PROTECT-RE term T${term}-SNMP from protocol udp`);
out.push(`set firewall family inet filter PROTECT-RE term T${term}-SNMP from destination-port snmp`);
out.push(`set firewall family inet filter PROTECT-RE term T${term}-SNMP then accept`);term++;
}
out.push(`set firewall family inet filter PROTECT-RE term REJECT-ALL then reject`);
if(fwEnable){
out.push(`set interfaces lo0 unit 0 family inet filter input PROTECT-RE`);
}
}
const snmpCom=v('snmp_community');
const snmpClients=v('snmp_clients');
if(snmpCom){
out.push(section('SNMP'));
out.push(`set snmp community ${snmpCom} authorization read-only`);
if(snmpClients) out.push(`set snmp community ${snmpCom} clients ${snmpClients}`);
if(hostname) out.push(`set snmp location "${hostname}"`);
out.push(`set snmp contact "Network Operations"`);
if(mgmtIp) out.push(`set snmp interface ${mgmtIf}`);
}
if(dtype==='srx'&&(cb('srx_zones')||cb('srx_nat'))){
const trustIf=v('srx_trust_if')||'ge-0/0/1';
const untrustIf=v('srx_untrust_if')||'ge-0/0/0';
if(cb('srx_zones')){
out.push(section('SRX — SECURITY ZONES'));
out.push(`set security zones security-zone trust host-inbound-traffic system-services all`);
out.push(`set security zones security-zone trust host-inbound-traffic protocols all`);
out.push(`set security zones security-zone trust interfaces ${trustIf}.0`);
out.push(`set security zones security-zone untrust screen untrust-screen`);
out.push(`set security zones security-zone untrust interfaces ${untrustIf}.0`);
out.push(`set security policies from-zone trust to-zone untrust policy PERMIT-ALL match source-address any`);
out.push(`set security policies from-zone trust to-zone untrust policy PERMIT-ALL match destination-address any`);
out.push(`set security policies from-zone trust to-zone untrust policy PERMIT-ALL match application any`);
out.push(`set security policies from-zone trust to-zone untrust policy PERMIT-ALL then permit`);
out.push(`set security screen ids-option untrust-screen icmp ping-death`);
out.push(`set security screen ids-option untrust-screen ip source-route-option`);
out.push(`set security screen ids-option untrust-screen tcp syn-flood`);
out.push(`set security screen ids-option untrust-screen tcp land`);
}
if(cb('srx_nat')){
out.push(section('SRX — SOURCE NAT'));
out.push(`set security nat source rule-set TRUST-TO-UNTRUST from zone trust`);
out.push(`set security nat source rule-set TRUST-TO-UNTRUST to zone untrust`);
out.push(`set security nat source rule-set TRUST-TO-UNTRUST rule SOURCE-NAT match source-address 0.0.0.0/0`);
out.push(`set security nat source rule-set TRUST-TO-UNTRUST rule SOURCE-NAT then source-nat interface`);
}
}
out.push(section('PROTOCOLS — LLDP & RSTP'));
out.push(`set protocols lldp interface all`);
out.push(`set protocols lldp-med interface all`);
if(dtype==='ex'||dtype==='qfx'){
out.push(`set protocols rstp`);
out.push(`set protocols rstp bridge-priority 32k`);
}
out.push(section('CHASSIS'));
if(dtype==='mx'){
out.push(`set chassis redundancy graceful-switchover`);
out.push(`set chassis network-services enhanced-ip`);
}
out.push(`set chassis alarm management-ethernet link-down ignore`);
out.push('\n## ─── END OF CONFIGURATION ───');
const html=out.map(line=>{
if(line.startsWith('##')) return `<span class="comment">${esc(line)}</span>`;
if(line.startsWith('set ')){
const parts=line.split(' ');
return `<span class="key">set</span> ${esc(parts.slice(1).join(' '))}`;
}
return esc(line);
}).join('\n');
document.getElementById('cfg-out').innerHTML=html;
document.getElementById('out-area').style.display='block';
document.getElementById('cfg-out').scrollIntoView({behavior:'smooth',block:'nearest'});
}
function esc(s){return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')}
function copyConfig(){
const el=document.getElementById('cfg-out');
const text=el.innerText;
navigator.clipboard.writeText(text).then(()=>{
const btn=document.getElementById('copy-btn');
btn.innerHTML='<i class="ti ti-check" aria-hidden="true"></i> Copied!';
setTimeout(()=>{btn.innerHTML='<i class="ti ti-copy" aria-hidden="true"></i> Copy'},1500);
});
}
addIface(); addVlan(); addStatic();
</script>