Hello! I’m new to genieacs and I’m trying to setup a workflow where the CPE devices initially connects with PPPoE into a walled garden (our LNS handles this with a realm identifier), gets it’s configuration from the within the walled garden, then can communicate publicly after that.
I have the ACS server setup with multiple interfaces:
- Management, UI, and NBI (private management network)
- CWMP and FS (walled garden)
- CWMP and FS (public internet)
The server is running genieacs 1.2.8 (built manually)
Through a combination of routing and a nginx reverse proxy, I have the services listening on the various interfaces and ports.
So far with some presets and provisions I can get some basic things configured, both within the walled garden and public interfaces.
The “catch 22” issue I’m running into is the order of operations…
Within my provision script I basically want to do the following:
- setup lan config
- setup wifi
- setup wan config (pppoe)
- change management url
But in doing so, I run into a preset_loop fault condition. Based on a tcpdump capture it looks like most of the time the management url (InternetGatewayDevice.ManagementServer.URL
) changes before the pppoe config applies (or vice versa) which results with the CPE no longer able to communicate with the ACS or the ACS unable to make a connection request to the CPE.
I have tried changing the order in which things are declared and have tried putting commit()
in various places (maybe I have a misunderstanding of this?)
I have also tried adjusting the some the ENV variable (like the batch size).
Is there something I can do to work around this or is this just a limitation of CWMP in general? Any insight or suggestions would be helpful.
Thanks.
References
Test provision scirpt
// TEST provisioning script
const now = Date.now();
log("\nDEBUG LOG: Provision started at " + now + "\n\n");
function setup_wan(now, args) {
log("setup_wan");
log(JSON.stringify(args));
//Ensure we have a WANPPPConnection instance
log("Creating WANPPPConnection (if necessary)");
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*", null, { path: 1 });
//Refresh the node...
log("Setting up WANPPPConnection");
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.*", { path: now });
//Setup static parameters
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.Name", { value: now }, { value: "pppoe_eth0" });
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.ConnectionType", { value: now }, { value: "IP_Routed" });
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.X_BROADCOM_COM_IfName", { value: now }, { value: "ppp0.1" });
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.NATEnabled", { value: now }, { value: true });
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.X_BROADCOM_COM_FirewallEnabled", { value: now }, { value: true });
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.Enable", { value: now }, { value: true });
//Setup customer parameters
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.Username", { value: now }, { value: args.ppp_username });
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.Password", { value: now }, { value: args.ppp_password });
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.Mtu", { value: now }, { value: args.ppp_wan_mtu });
declare("InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.*.PPPoEServiceName", { value: now }, { value: "internet" });
// ip masked out.... it's a public ip
declare("InternetGatewayDevice.ManagementServer.URL", { value: now }, { value: "http://***.***.***.***:8085" });
}
function setup_lan(now, args) {
log("setup_lan");
log(JSON.stringify(args));
// refresh node
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.*", { path: now });
//
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.DHCPServerEnable", { value: now }, { value: args.dhcp_en });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.DHCPServerConfigurable", { value: now }, { value: true });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.DHCPLeaseTime", { value: now }, { value: 86400 });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.DHCPRelay", { value: now }, { value: false });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.DNSServers", { value: now }, { value: "0.0.0.0,0.0.0.0" });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.MinAddress", { value: now }, { value: args.dhcp_range.from });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.MaxAddress", { value: now }, { value: args.dhcp_range.to });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.SubnetMask", { value: now }, { value: args.netmask });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.TftpServerEnable", { value: now }, { value: false });
//declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.X_COMTREND_COM_ReservedIPSize", { value: now }, { value: args.dhcp_range_size });
//Ensure we have an IPInterface instance
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.IPInterface.*", null, { path: 1 });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.IPInterface.1.Enable", { value: now }, { value: true });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.IPInterface.1.IPInterfaceAddressingType", { value: now }, { value: "Static" });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.IPInterface.1.IPInterfaceIPAddress", { value: now }, { value: args.gateway });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.IPInterface.1.IPInterfaceSubnetMask", { value: now }, { value: args.netmask });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.IPInterface.1.X_BROADCOM_COM_IfName", { value: now }, { value: "br0" });
declare("InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.IPInterface.1.X_BROADCOM_COM_DhcpDefaultGateway", { value: now }, { value: "0.0.0.0" });
}
function setup_wifi(now, args) {
log("TODO: Setup Wi-Fi");
log("setup_lan");
log(JSON.stringify(args));
}
function setup_firewall(now, args) {
log("TODO: Firewall");
log("setup_firewall");
log(JSON.stringify(args));
}
let provisioned = declare("Tags.Provisioned", { value: 1 });
if (provisioned.value !== undefined) {
log("CPE is (allegedly) provisioned, returning");
return;
}
// get details of CPE to uniquiely identify it...
let model = declare("InternetGatewayDevice.DeviceInfo.ModelName", { value: 1 }).value[0];
let serialNumber = declare("DeviceID.SerialNumber", { value: 1 }).value[0];
let productClass = declare("DeviceID.ProductClass", { value: 1 }).value[0];
let oui = declare("DeviceID.OUI", { value: 1 }).value[0];
let args = { serial: serialNumber, productClass: productClass, oui: oui };
//Allow LAN+WAN Ping
declare("InternetGatewayDevice.X_BROADCOM_COM_AppCfg.IcmpCfg.NetworkAccess", null, { value: "LAN or WAN" });
setup_lan(now, ext("cpe-config", "get_lan_config", args));
// setup_wifi(now, ext("cpe-config", "get_wifi_config", args));
// setup_firewall(now, ext("cpe-config", "get_firewall_config", args));
commit();
setup_wan(now, ext("cpe-config", "get_pppoe_config", args));
commit();
/**
* Done confing, set Provisioned tag
*/
log('Done configuring. Setting provisioned tag');
declare("Tags.Provisioned", null, { value: true });
env file
NODE_OPTIONS=--enable-source-maps
GENIEACS_CWMP_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-cwmp-access.log
GENIEACS_NBI_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-nbi-access.log
GENIEACS_FS_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-fs-access.log
GENIEACS_UI_ACCESS_LOG_FILE=/var/log/genieacs/genieacs-ui-access.log
GENIEACS_CWMP_LOG_FILE=/var/log/genieacs/genieacs-cwmp.log
GENIEACS_NBI_LOG_FILE=/var/log/genieacs/genieacs-nbi.log
GENIEACS_FS_LOG_FILE=/var/log/genieacs/genieacs-fs.log
GENIEACS_UI_LOG_FILE=/var/log/genieacs/genieacs-ui.log
GENIEACS_DEBUG=TRUE
GENIEACS_DEBUG_FORMAT=yaml
GENIEACS_DEBUG_FILE=/var/log/genieacs/genieacs-debug.yaml
GENIEACS_EXT_DIR=/opt/genieacs/ext
GENIEACS_UI_JWT_SECRET=<its a secret>
GENIEACS_UI_PORT=8080
GENIEACS_UI_INTERFACE=127.0.0.1
GENIEACS_NBI_PORT=7557
GENIEACS_NBI_INTERFACE=127.0.0.1
GENIEACS_CWMP_PORT=7547
GENIEACS_CWMP_INTERFACE=127.0.0.1
GENIEACS_FS_PORT=7567
GENIEACS_FS_INTERFACE=127.0.0.1
GENIEACS_SESSION_TIMEOUT=600
GENIEACS_GPN_NEXT_LEVEL=4
GENIEACS_GPV_BATCH_SIZE=128
GENIEACS_MAX_DEPTH=8
GENIEACS_MAX_COMMIT_ITERATIONS=128
# GENIEACS_CONNECTION_REQUEST_TIMEOUT=3000
# GENIEACS_DEVICE_ONLINE_THRESHOLD=6000 probably don't set this?
nginx config
# /etc/nginx/sites-available/genieacs.conf
# Nginx configuration for genieacs services
# Ensure you change the listening IP address
# If you're allergic to security, you can remove the `add_header`
# lines without breaking functionality
upstream genieacs-gui {
server 127.0.0.1:8080;
}
upstream genieacs-cwmp {
server 127.0.0.1:7547;
}
upstream genieacs-nbi {
server 127.0.0.1:7557;
}
upstream genieacs-fs {
server 127.0.0.1:7567;
}
server {
listen 80 default_server;
server_name genie-acs.domain.tld;
add_header Content-Security-Policy "default-src 'self'" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "sameorigin" always;
add_header X-XSS-Protection "1; mode block" always;
location /.well-known {
alias /var/www/html/.well-known;
}
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name genie-acs.domain.tld;
ssl_certificate_key /path/to/server.key;
ssl_certificate /path/to/certificate.pem;
access_log /var/log/nginx/genieacs-web-access.log combined;
error_log /var/log/nginx/genieacs-web-error.log;
client_max_body_size 50M;
root /opt/genieacs/public;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline'" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "sameorigin" always;
add_header X-XSS-Protection "1; mode block" always;
location /.well-known {
alias /var/www/html/.well-known;
}
location / {
try_files $uri $uri/index.html @app;
}
location @app {
proxy_pass http://genieacs-gui;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
server {
listen 10.42.0.2:8085;
access_log /var/log/nginx/genieacs-cwmp-access.log combined;
error_log /var/log/nginx/genieacs-cwmp-error.log;
client_max_body_size 50M;
add_header Content-Security-Policy "default-src 'self'" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "sameorigin" always;
add_header X-XSS-Protection "1; mode block" always;
location / {
proxy_pass http://genieacs-cwmp;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
proxy_set_header Authorization "";
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/ms-htpasswd;
}
}
server {
listen <public_ip>:8085;
access_log /var/log/nginx/genieacs-cwmp-access.log combined;
error_log /var/log/nginx/genieacs-cwmp-error.log;
client_max_body_size 50M;
add_header Content-Security-Policy "default-src 'self'" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "sameorigin" always;
add_header X-XSS-Protection "1; mode block" always;
location / {
proxy_pass http://genieacs-cwmp;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
proxy_set_header Authorization "";
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/ms-htpasswd;
}
}
server {
listen 192.168.7.189:7557 ssl;
server_name genie-acs.domain.tld;
ssl_certificate_key /path/to/server.key;
ssl_certificate /path/to/certificate.pem;
access_log /var/log/nginx/genieacs-nbi-access.log combined;
error_log /var/log/nginx/genieacs-nbi-error.log;
client_max_body_size 50M;
add_header Strict-Transport-Security "max-age=31536000" always;
add_header Content-Security-Policy "default-src 'self'" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "sameorigin" always;
add_header X-XSS-Protection "1; mode block" always;
location / {
proxy_pass http://genieacs-nbi;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
proxy_set_header Authorization "";
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/ms-htpasswd;
}
}
server {
listen 10.42.0.2:7567;
access_log /var/log/nginx/genieacs-fs-access.log combined;
error_log /var/log/nginx/genieacs-fs-error.log;
client_max_body_size 50M;
add_header Content-Security-Policy "default-src 'self'" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "sameorigin" always;
add_header X-XSS-Protection "1; mode block" always;
location / {
proxy_pass http://genieacs-fs;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
proxy_set_header Authorization "";
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/ms-htpasswd;
}
}
interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug ens192
iface ens192 inet static
address 192.168.7.189/24
gateway 192.168.7.1
dns-nameservers 192.168.7.55 192.168.7.100
allow-hotplug ens224
iface ens224 inet static
address 10.42.0.2/24
post-up ip route add 10.99.0.0/24 via 10.42.0.1
pre-down route del 10.99.0.0/24
allow-hotplug ens256
iface ens256 inet static
address <public_ip>/26
post-up ip route add <cpe_pool_1>/20 via <default_gateway>
post-up ip route add <cpe_pool_2>/24 via <default_gateway>
post-up ip route add <cpe_pool_3>/18 via <default_gateway>
post-up ip route add <cpe_pool_4>/22 via <default_gateway>
pre-down route del <cpe_pool_1>/20
pre-down route del <cpe_pool_2>/24
pre-down route del <cpe_pool_3>/18
pre-down route del <cpe_pool_4>/22