Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ RUN curl -o /usr/share/keyrings/opensips-org.gpg https://apt.opensips.org/opensi
# 3. Install OpenSIPS & Modules
RUN apt-get -y update -qq && apt-get -y install opensips opensips-mysql-module \
opensips-regex-module opensips-restclient-module opensips-http-modules \
opensips-json-module opensips-tls-module opensips-auth-modules opensips-wss-module make && \
opensips-json-module opensips-tls-module opensips-auth-modules opensips-wss-module opensips-stir-shaken-module make && \
rm -rf /var/lib/apt/lists/*

# 4. Setup Dual Logging Routing (rsyslog)
Expand Down
58 changes: 54 additions & 4 deletions configs/opensips.cfg.template
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ loadmodule "rtpengine.so"
modparam("rtpengine", "db_url", "mysql://{{{db_user}}}:{{{db_pass}}}@{{{db_host}}}/{{{db_opensips}}}")
#modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:2223")

loadmodule "stir_shaken.so"
# Path to your signing certificate (Public Key)
modparam("stir_shaken", "ca_list", "/etc/opensips/tls/vs/ca_bundle.crt")


loadmodule "uac.so"

#### ACCounting module
Expand Down Expand Up @@ -413,6 +418,48 @@ route{
route(RELAY);
}

route[AS_SERVICE] {
# 1. Define your parameters
$var(attest) = "A"; # Attestation Level (A, B, or C)
$var(origid) = "your-orig-uuid"; # Your UUID/Originating ID
$var(cert) = "/etc/opensips/tls/vs/cert.pem"; # Local Path to Public Cert
$var(key) = "/etc/opensips/tls/vs/key.pem"; # Local Path to Private Key

# The X5U is the URL where the CALLEE can download your public cert
$var(x5u) = "https://{{{deployment_domain}}}/stir-shaken/cert.pem";

# 2. Call the function with correct parameter order:
# stir_shaken_auth(attest, origid, cert, pkey, x5u)
if (!stir_shaken_auth($var(attest), $var(origid), $var(cert), $var(key), $var(x5u))) {
xlog("L_ERR", "STIR/SHAKEN signing failed with error code $rc!\n");
# Optional: You may want to exit or send a reply if signing is mandatory
} else {
xlog("L_INFO", "STIR/SHAKEN Identity header successfully generated\n");
}
}

route[VS_SERVICE] {
if (is_present_hf("Identity")) {
# 1. Provide the variable names directly (no quotes)
# OpenSIPS will populate these variables automatically on call
if (stir_shaken_verify($var(cert_out), $var(err_code), $var(err_reason))) {
xlog("L_INFO", "STIR/SHAKEN Verification Successful - Identity Verified\n");
} else {
# 2. Now you can use them as normal with the $ prefix
xlog("L_WARN", "STIR/SHAKEN Verification Failed - Code: $var(err_code) Reason: $var(err_reason)\n");

if ($var(err_code) == "-4") {
send_reply(438, "Stale Identity Header");
} else {
send_reply(438, "Invalid Identity Header");
}
exit;
}
} else {
xlog("L_INFO", "No Identity header present to verify\n");
}
}

route[WITHINDLG] {
# Handle in-dialog requests (ACK/BYE/reINVITE/UPDATE/INFO/OPTIONS/etc.)
# Must be called only when has_totag() is true.
Expand Down Expand Up @@ -664,6 +711,9 @@ route[INTERNAL_EXTENSION_ROUTING] {

route[PSTN_ROUTING] {
xlog("SOURCE IP IS: $si");

# STIR/SHAKEN verification
# route(VS_SERVICE);
if ($hdr(X-LineBlocs-RingSubscriber) == "true")
{
xlog("sending to extension...\r\n");
Expand Down Expand Up @@ -812,7 +862,7 @@ route[INCOMING_VALIDATION_2] {
route[DID_ASSIGNED] {
if ($var(rcode) != 200)
{
send_reply(400, "Bad Request -- DID lookup failed");
send_reply(400, "Bad Request (scenario 1)");
exit;
}

Expand All @@ -828,7 +878,7 @@ route[DID_ASSIGNED] {
route[TRUNK_ASSIGNED] {
if ($var(rcode) != 200)
{
send_reply(400, "Bad Request");
send_reply(400, "Bad Request (scenario 2)");
exit;
}

Expand All @@ -845,7 +895,7 @@ route[TRUNK_ASSIGNED] {
route[CALL_ACTION] {
if ($var(rcode) != 200)
{
send_reply(400, "Bad Request");
send_reply(400, "Bad Request (scenario 3)");
exit;
}

Expand Down Expand Up @@ -1588,4 +1638,4 @@ route[RTPENGINE_ANSWER] {
rtpengine_use_set(1);
xlog("L_INFO", "RTP Answer Flags: $var(ans_flags)\n");
rtpengine_answer("$var(ans_flags)");
}
}
15 changes: 15 additions & 0 deletions tls/vs/ca_bundle.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICSzCCAfGgAwIBAgIUL1NXIQGwQ1KYrDV2jUm1h2jcuWgwCgYIKoZIzj0EAwIw
ezELMAkGA1UEBhMCQ0ExEDAOBgNVBAgMB0FsYmVydGExETAPBgNVBAcMCEVkbW9u
dG9uMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxJDAiBgkqhkiG
9w0BCQEWFW5oYW1pZEBkeW5hbW9jbG91ZC5jYTAeFw0yNjA0MTMwMDI2NDBaFw0y
NzA0MTMwMDI2NDBaMHsxCzAJBgNVBAYTAkNBMRAwDgYDVQQIDAdBbGJlcnRhMREw
DwYDVQQHDAhFZG1vbnRvbjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkg
THRkMSQwIgYJKoZIhvcNAQkBFhVuaGFtaWRAZHluYW1vY2xvdWQuY2EwWTATBgcq
hkjOPQIBBggqhkjOPQMBBwNCAAThGp9Vwm6X9rKZaRujtr75d7Ll7hfPcM0s1mp7
Cne5SeueDGvYALmaLHtvMMzHC1vI4KxeUfJuPEdeZptQSOngo1MwUTAdBgNVHQ4E
FgQUIFeNyAHqObnvm/XCtqQL5SgUiWMwHwYDVR0jBBgwFoAUIFeNyAHqObnvm/XC
tqQL5SgUiWMwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEAoqYv
39l3OS/Q6GLcBC7d1yGBoih10+haa/YM+7l+UTYCIB7F32kL8J0W70t5M/k6zdWQ
5O/O+pS/162fbt6VEOev
-----END CERTIFICATE-----
15 changes: 15 additions & 0 deletions tls/vs/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICSzCCAfGgAwIBAgIUL1NXIQGwQ1KYrDV2jUm1h2jcuWgwCgYIKoZIzj0EAwIw
ezELMAkGA1UEBhMCQ0ExEDAOBgNVBAgMB0FsYmVydGExETAPBgNVBAcMCEVkbW9u
dG9uMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxJDAiBgkqhkiG
9w0BCQEWFW5oYW1pZEBkeW5hbW9jbG91ZC5jYTAeFw0yNjA0MTMwMDI2NDBaFw0y
NzA0MTMwMDI2NDBaMHsxCzAJBgNVBAYTAkNBMRAwDgYDVQQIDAdBbGJlcnRhMREw
DwYDVQQHDAhFZG1vbnRvbjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkg
THRkMSQwIgYJKoZIhvcNAQkBFhVuaGFtaWRAZHluYW1vY2xvdWQuY2EwWTATBgcq
hkjOPQIBBggqhkjOPQMBBwNCAAThGp9Vwm6X9rKZaRujtr75d7Ll7hfPcM0s1mp7
Cne5SeueDGvYALmaLHtvMMzHC1vI4KxeUfJuPEdeZptQSOngo1MwUTAdBgNVHQ4E
FgQUIFeNyAHqObnvm/XCtqQL5SgUiWMwHwYDVR0jBBgwFoAUIFeNyAHqObnvm/XC
tqQL5SgUiWMwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEAoqYv
39l3OS/Q6GLcBC7d1yGBoih10+haa/YM+7l+UTYCIB7F32kL8J0W70t5M/k6zdWQ
5O/O+pS/162fbt6VEOev
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions tls/vs/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIHQ9A7eboPAePSYseNa2XKmgB6OuH4yr13T1Rb2LVvT+oAoGCCqGSM49
AwEHoUQDQgAE4RqfVcJul/aymWkbo7a++Xey5e4Xz3DNLNZqewp3uUnrngxr2AC5
mix7bzDMxwtbyOCsXlHybjxHXmabUEjp4A==
-----END EC PRIVATE KEY-----
Loading