Automated configuration of GlobalProtect Gateway with XML API or CLI

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Please sign in to see details of an important advisory in our Customer Advisories area.

Automated configuration of GlobalProtect Gateway with XML API or CLI

L2 Linker

 

I have a requirement to configure GlobalProtect on-demand with code on PAs. I am stuck on Network > GlobalProtect > Gateways.
My code calls the XML API and creates certificates, imports public cert, imports SAML file, creates GP portal, add firewall rules etc
I am able to configure all that and GlobalProtect > Portals just fine, just not the Gateway.

The API path to create the GlobalProtect Gateway config is:

$apiURL = "https://" + $panAddress + "//api/?key=" + $pankey +
"&type=config&action=set&xpath=/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/global-protect/global-protect-gateway/entry[@name='MY-GP-GATEWAY']&element<etc etc ...>

In the web GUI, when you add a new gateway in asks for an Interface. The API browser does NOT have an element for Interface. I thought that I could look at the CLI commands and convert them to API, but there is no choice for Interface there either. Here are the options.


set global-protect global-protect-gateway MY-GP-GATEWAY ?

+ block-quarantined-devices    Block login for quarantined devices
+ certificate-profile          Profile for authenticating client certificates
+ log-fail                     Log unsuccessful TLS handshakes
+ log-setting                  log-setting
+ log-success                  Log successful TLS handshakes
+ remote-user-tunnel           GlobalProtect user tunnel
+ satellite-tunnel             GlobalProtect satellite tunnel
+ ssl-tls-service-profile      SSL TLS service profile
+ tunnel-mode                  Tunnel mode
> client-auth                  GlobalProtect portal client authentication
> hip-notification             host PC health evaluate
> local-address                Local IP configuration
> remote-user-tunnel-configs   GlobalProtect gateway remote user tunnel configurations
> roles                        role based user management for GlobalProtect gateway users
> security-restrictions        Security Hardening for GlobalProtect
  <Enter>                      Finish input


Also I have another PA that has the whole configuration done manually. When I GET that config with the API, the output shows no element for Interface.

So I can run a SET api call which includes as much info as possible, and it does create the gateway. When I look at it in the GUI, the Interface and the Tunnel Interface are blank. If I fill them in manually, I can then commit.
This then causes a new gateway with a "-N" at the end to be created, you can't see it in the GUI, but it can be seen in the API browser at

/config/devices/entry[@name='localhost.localdomain']/network/tunnel/global-protect-gateway/entry[@name='MY-GP-GATEWAY-N'] --- what is that?

Then look at NETWORK > Interfaces > Tunnel .. and I see the GP feature on the tunnel interface with "MY-GP-GATEWAY-N" when I hover over it.
I have tried creating MY-GP-GATEWAY first and MY-GP-GATEWAY-N second, and vice versa, no luck.
What is the proper way to configure the GP Gateway with CLI or API without having to do anything in the web gui?

And just for reference, here is the API call I use to create the (partial) gateway config. I call it from powershell. Certs and Profiles are included as variables.

 

$apiURL = "https://" + $panAddress + "//api/?key=" + $pankey +
"&type=config&action=set&xpath=/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/global-protect/global-protect-gateway/entry[@name='$gtwyProfile']
&element=<client-auth>
<entry name='$gtwyAuthProf'>
<os>Any</os>
<authentication-profile>$authProfile</authentication-profile>
<authentication-message>Enter login credentials</authentication-message>
<user-credential-or-client-cert-required>yes</user-credential-or-client-cert-required>
<username-label>Username</username-label>
<password-label>Password</password-label>
</entry>
</client-auth>
<remote-user-tunnel-configs>
<entry name='$gtwyAuthConf'>
<split-tunneling><include-domains><list/></include-domains>
<exclude-domains><list/></exclude-domains>
<access-route>
<member>10.6.0.0/16</member>
<member>10.7.0.0/16</member>
</access-route>
<exclude-access-route/>
<include-applications/>
<exclude-applications/>
</split-tunneling>
<authentication-override>
<cookie-encrypt-decrypt-cert>$samlCert</cookie-encrypt-decrypt-cert>
<generate-cookie>yes</generate-cookie>
</authentication-override>
<ip-pool>
<member>10.81.92.192/27</member>
</ip-pool>
</entry>
</remote-user-tunnel-configs>
<ssl-tls-service-profile>$sslprofile</ssl-tls-service-profile>
<tunnel-mode>yes</tunnel-mode>&target=$serial"

Invoke-WebRequest -uri $apiURL

1 accepted solution

Accepted Solutions

L5 Sessionator

Hi @RogerMccarrick,

 

Understood. Originally I was just trying to answer the interface query, but I took a broader look at the config elements for GP Gateway and here's what I observed when I looked at the XML config for a successfully configured and working GP Gateway.

 

The config for a Gateway is split across two Xpaths:

/config/devices/entry[@name='localhost.localdomain']/network/tunnel/global-protect-gateway

and

/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/global-protect/global-protect-gateway

which may explain the challenges you are facing if you are (an assumption from your original post) only targeting the latter of these. A debug of the GUI shows two set calls, one to each Xpath.

 

Under the first Xpath it seems to look like this:

<global-protect-gateway>
    <entry name="gateway-N">
        <client>
            <exclude-video-traffic>
                <applications />
                <enabled>yes</enabled>
            </exclude-video-traffic>
            <dns-server>
                <primary>192.168.1.1</primary>
                <secondary>8.8.8.8</secondary>
            </dns-server>
            <dns-suffix>
                <member>test.local</member>
            </dns-suffix>
            <dns-suffix-inherited>no</dns-suffix-inherited>
        </client>
        <ipsec>
            <third-party-client>
                <enable>no</enable>
            </third-party-client>
        </ipsec>
        <local-address>
            <interface>ethernet1/3</interface>
            <ip>
                <ipv4>192.168.190.254/24</ipv4>
            </ip>
        </local-address>
        <ip-pool>
            <member>192.168.170.128-192.168.170.191</member>
        </ip-pool>
        <tunnel-interface>tunnel.1</tunnel-interface>
    </entry>
</global-protect-gateway>

 

And under the second it looks like this:

<global-protect-gateway>
    <entry name="gateway">
        <roles>
            <entry name="default">
                <login-lifetime>
                    <days>30</days>
                </login-lifetime>
                <inactivity-logout>10</inactivity-logout>
            </entry>
        </roles>
        <client-auth>
            <entry name="mfa">
                <os>Any</os>
                <authentication-profile>mfa-auth-profile</authentication-profile>
                <authentication-message>Enter login credentials</authentication-message>
                <user-credential-or-client-cert-required>yes</user-credential-or-client-cert-required>
                <auto-retrieve-passcode>no</auto-retrieve-passcode>
                <username-label>Username</username-label>
                <password-label>Password</password-label>
            </entry>
            <entry name="Local">
                <os>Any</os>
                <authentication-profile>local-auth-profile</authentication-profile>
                <authentication-message>Enter login credentials</authentication-message>
                <user-credential-or-client-cert-required>yes</user-credential-or-client-cert-required>
                <auto-retrieve-passcode>no</auto-retrieve-passcode>
                <username-label>Username</username-label>
                <password-label>Password</password-label>
            </entry>
        </client-auth>
        <remote-user-tunnel-configs>
            <entry name="gp-client">
                <authentication-override>
                    <accept-cookie>
                        <cookie-lifetime>
                            <lifetime-in-days>30</lifetime-in-days>
                        </cookie-lifetime>
                    </accept-cookie>
                    <cookie-encrypt-decrypt-cert>pan-os-sub-ca</cookie-encrypt-decrypt-cert>
                    <generate-cookie>no</generate-cookie>
                </authentication-override>
                <split-tunneling>
                    <access-route>
                        <member>0.0.0.0/0</member>
                    </access-route>
                </split-tunneling>
                <source-user>
                    <member>any</member>
                </source-user>
                <dns-server>
                    <member>192.168.1.254</member>
                </dns-server>
                <dns-suffix>
                    <member>test.local</member>
                </dns-suffix>
                <os>
                    <member>any</member>
                </os>
                <retrieve-framed-ip-address>no</retrieve-framed-ip-address>
                <no-direct-access-to-local-network>no</no-direct-access-to-local-network>
            </entry>
        </remote-user-tunnel-configs>
        <ssl-tls-service-profile>cert-profile</ssl-tls-service-profile>
        <tunnel-mode>yes</tunnel-mode>
        <remote-user-tunnel>tunnel.1</remote-user-tunnel>
        <log-success>yes</log-success>
        <log-setting>default</log-setting>
    </entry>
</global-protect-gateway>

 

I created two XML API calls to replicate all this, they looked like this:

https://{{host}}/api/?key={{key}}&type=config&action=set&xpath=/config/devices/entry[@name='localhost.localdomain']/network/tunnel/global-protect-gateway/entry[@name='new-gw-N']&element=<local-address><ip><ipv4>192.168.1.1/24</ipv4></ip><interface>ethernet1/4</interface><ip-address-family>ipv4</ip-address-family></local-address><client><exclude-video-traffic><applications/><enabled>no</enabled></exclude-video-traffic></client><ipsec><third-party-client><enable>no</enable></third-party-client></ipsec><ip-pool/><tunnel-interface>tunnel.2</tunnel-interface>

and this:

https://{{host}}/api/?key={{key}}&type=config&action=set&xpath=/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/global-protect/global-protect-gateway/entry[@name='new-gw']&element=<roles><entry name="default"><login-lifetime><days>30</days></login-lifetime><inactivity-logout>180</inactivity-logout></entry></roles><client-auth><entry name="local"><os>Any</os><authentication-profile>local-auth-profile</authentication-profile><authentication-message>Enter login credentials</authentication-message><user-credential-or-client-cert-required>no</user-credential-or-client-cert-required><auto-retrieve-passcode>no</auto-retrieve-passcode><username-label>Username</username-label><password-label>Password</password-label></entry></client-auth><remote-user-tunnel-configs><entry name="new-gw"><split-tunneling><include-domains><list/></include-domains><exclude-domains><list/></exclude-domains><access-route/><exclude-access-route/><include-applications/><exclude-applications/></split-tunneling><authentication-override><generate-cookie>no</generate-cookie></authentication-override><source-address><ip-address/><region/></source-address><source-user><member>any</member></source-user><authentication-server-ip-pool/><ip-pool><member>10.10.10.10-10.10.10.20</member></ip-pool><os><member>any</member></os><retrieve-framed-ip-address>no</retrieve-framed-ip-address><no-direct-access-to-local-network>no</no-direct-access-to-local-network></entry></remote-user-tunnel-configs><ssl-tls-service-profile>cert-profile</ssl-tls-service-profile><log-success>yes</log-success><log-setting>default</log-setting><tunnel-mode>yes</tunnel-mode><remote-user-tunnel>tunnel.2</remote-user-tunnel>

and that seemed to create a valid GP Gateway, including the items you have called out as an issue, like interface, tunnel mode, tunnel interface, etc.

 

I hope this helps to give you more insight and a path forward.

Help the community: "Like" helpful comments, and click "Accept as Solution" if you found your answer 🙂

View solution in original post

5 REPLIES 5

L5 Sessionator

Hi @RogerMccarrick,

If I understand correctly, the element you are looking for to set the interface where the GP Gateway will be served/listening, is underneath "local-address"?

 

set global-protect global-protect-gateway test local-address interface ...

 

<global-protect-gateway>
   <entry name="test">
   .
   .
   <local-address>
      <interface>ethernet1/1</interface>
      <ip>
         <ipv4>192.168.1.1/24</ipv4>
      </local-address>
      .
      .

 

With this information hopefully you can amend/update you original XML API call and not go through any manual GUI work, just API?

 

Hope that helps?

Help the community: "Like" helpful comments, and click "Accept as Solution" if you found your answer 🙂

Thanks Jimmy. I had seen and tried these elements before, but I didn't mention it in my previous post.
Unfortunately it didn't work for me. I've tried to step through the GP Gateway (TEST-GP-GATEWAY) creation one step at a time.

 

First, the interface and IP:

&element=<local-address>
<ip><ipv4>untrust-ip</ipv4></ip>
<interface>ethernet1/1</interface>
<ip-address-family>ipv4</ip-address-family>
</local-address>

This succeeds, in the GUI, I see the interface and IP are set.
Of course the Authentication and Agent tabs have yet to be configured.

 

Next, authentication

&element=<client-auth>
<entry name='$gtwyAuthProf'>
<os>Any</os>
<authentication-profile>$authProfile</authentication-profile>
<authentication-message>Enter login credentials</authentication-message>
<user-credential-or-client-cert-required>yes</user-credential-or-client-cert-required>
<username-label>Username</username-label>
<password-label>Password</password-label>
</entry>
</client-auth>
<ssl-tls-service-profile>$sslprofile</ssl-tls-service-profile>

This also succeeds, and I see the Authentication settings in the GUI.


Next is Agent, I want to check Tunnel Mode and select the tunnel interface 501 that I have already created and committed with code.

&element=<tunnel-mode>yes</tunnel-mode>
<remote-user-tunnel>tunnel.501</remote-user-tunnel>

This fails with:
status="error"
code="12"
[CDATA[ TEST-GP-GATEWAY -> remote-user-tunnel 'tunnel.501' is not a valid reference
[CDATA[ TEST-GP-GATEWAY -> remote-user-tunnel is invalid]


Next, I tried to set tunnel mode, but not specify the tunnel interface yet

&element=<tunnel-mode>yes</tunnel-mode>

This succeeds ... but in the GUI, when I click on the Gateway and open it, it shows the interface and IPv4 address as NOT selected.

 

As I previously stated, I can select and set everything in the GUI, so I don't know why it says tunnel.501 is invalid.
I can get some of config done, including the interface and IP, but now the invalid Tunnel Interface has become the obstacle.

Also for GlobalProtect IPSec Crypto under Agent, <ipsec-crypto-profile>TEST-GPVPN-CRYPTO</ipsec-crypto-profile> isnt working.

 

I have a ticket open with support and they say they have to get me to talk to a Sales Engineer. So still working on it.

 

L5 Sessionator

Hi @RogerMccarrick,

 

Understood. Originally I was just trying to answer the interface query, but I took a broader look at the config elements for GP Gateway and here's what I observed when I looked at the XML config for a successfully configured and working GP Gateway.

 

The config for a Gateway is split across two Xpaths:

/config/devices/entry[@name='localhost.localdomain']/network/tunnel/global-protect-gateway

and

/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/global-protect/global-protect-gateway

which may explain the challenges you are facing if you are (an assumption from your original post) only targeting the latter of these. A debug of the GUI shows two set calls, one to each Xpath.

 

Under the first Xpath it seems to look like this:

<global-protect-gateway>
    <entry name="gateway-N">
        <client>
            <exclude-video-traffic>
                <applications />
                <enabled>yes</enabled>
            </exclude-video-traffic>
            <dns-server>
                <primary>192.168.1.1</primary>
                <secondary>8.8.8.8</secondary>
            </dns-server>
            <dns-suffix>
                <member>test.local</member>
            </dns-suffix>
            <dns-suffix-inherited>no</dns-suffix-inherited>
        </client>
        <ipsec>
            <third-party-client>
                <enable>no</enable>
            </third-party-client>
        </ipsec>
        <local-address>
            <interface>ethernet1/3</interface>
            <ip>
                <ipv4>192.168.190.254/24</ipv4>
            </ip>
        </local-address>
        <ip-pool>
            <member>192.168.170.128-192.168.170.191</member>
        </ip-pool>
        <tunnel-interface>tunnel.1</tunnel-interface>
    </entry>
</global-protect-gateway>

 

And under the second it looks like this:

<global-protect-gateway>
    <entry name="gateway">
        <roles>
            <entry name="default">
                <login-lifetime>
                    <days>30</days>
                </login-lifetime>
                <inactivity-logout>10</inactivity-logout>
            </entry>
        </roles>
        <client-auth>
            <entry name="mfa">
                <os>Any</os>
                <authentication-profile>mfa-auth-profile</authentication-profile>
                <authentication-message>Enter login credentials</authentication-message>
                <user-credential-or-client-cert-required>yes</user-credential-or-client-cert-required>
                <auto-retrieve-passcode>no</auto-retrieve-passcode>
                <username-label>Username</username-label>
                <password-label>Password</password-label>
            </entry>
            <entry name="Local">
                <os>Any</os>
                <authentication-profile>local-auth-profile</authentication-profile>
                <authentication-message>Enter login credentials</authentication-message>
                <user-credential-or-client-cert-required>yes</user-credential-or-client-cert-required>
                <auto-retrieve-passcode>no</auto-retrieve-passcode>
                <username-label>Username</username-label>
                <password-label>Password</password-label>
            </entry>
        </client-auth>
        <remote-user-tunnel-configs>
            <entry name="gp-client">
                <authentication-override>
                    <accept-cookie>
                        <cookie-lifetime>
                            <lifetime-in-days>30</lifetime-in-days>
                        </cookie-lifetime>
                    </accept-cookie>
                    <cookie-encrypt-decrypt-cert>pan-os-sub-ca</cookie-encrypt-decrypt-cert>
                    <generate-cookie>no</generate-cookie>
                </authentication-override>
                <split-tunneling>
                    <access-route>
                        <member>0.0.0.0/0</member>
                    </access-route>
                </split-tunneling>
                <source-user>
                    <member>any</member>
                </source-user>
                <dns-server>
                    <member>192.168.1.254</member>
                </dns-server>
                <dns-suffix>
                    <member>test.local</member>
                </dns-suffix>
                <os>
                    <member>any</member>
                </os>
                <retrieve-framed-ip-address>no</retrieve-framed-ip-address>
                <no-direct-access-to-local-network>no</no-direct-access-to-local-network>
            </entry>
        </remote-user-tunnel-configs>
        <ssl-tls-service-profile>cert-profile</ssl-tls-service-profile>
        <tunnel-mode>yes</tunnel-mode>
        <remote-user-tunnel>tunnel.1</remote-user-tunnel>
        <log-success>yes</log-success>
        <log-setting>default</log-setting>
    </entry>
</global-protect-gateway>

 

I created two XML API calls to replicate all this, they looked like this:

https://{{host}}/api/?key={{key}}&type=config&action=set&xpath=/config/devices/entry[@name='localhost.localdomain']/network/tunnel/global-protect-gateway/entry[@name='new-gw-N']&element=<local-address><ip><ipv4>192.168.1.1/24</ipv4></ip><interface>ethernet1/4</interface><ip-address-family>ipv4</ip-address-family></local-address><client><exclude-video-traffic><applications/><enabled>no</enabled></exclude-video-traffic></client><ipsec><third-party-client><enable>no</enable></third-party-client></ipsec><ip-pool/><tunnel-interface>tunnel.2</tunnel-interface>

and this:

https://{{host}}/api/?key={{key}}&type=config&action=set&xpath=/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/global-protect/global-protect-gateway/entry[@name='new-gw']&element=<roles><entry name="default"><login-lifetime><days>30</days></login-lifetime><inactivity-logout>180</inactivity-logout></entry></roles><client-auth><entry name="local"><os>Any</os><authentication-profile>local-auth-profile</authentication-profile><authentication-message>Enter login credentials</authentication-message><user-credential-or-client-cert-required>no</user-credential-or-client-cert-required><auto-retrieve-passcode>no</auto-retrieve-passcode><username-label>Username</username-label><password-label>Password</password-label></entry></client-auth><remote-user-tunnel-configs><entry name="new-gw"><split-tunneling><include-domains><list/></include-domains><exclude-domains><list/></exclude-domains><access-route/><exclude-access-route/><include-applications/><exclude-applications/></split-tunneling><authentication-override><generate-cookie>no</generate-cookie></authentication-override><source-address><ip-address/><region/></source-address><source-user><member>any</member></source-user><authentication-server-ip-pool/><ip-pool><member>10.10.10.10-10.10.10.20</member></ip-pool><os><member>any</member></os><retrieve-framed-ip-address>no</retrieve-framed-ip-address><no-direct-access-to-local-network>no</no-direct-access-to-local-network></entry></remote-user-tunnel-configs><ssl-tls-service-profile>cert-profile</ssl-tls-service-profile><log-success>yes</log-success><log-setting>default</log-setting><tunnel-mode>yes</tunnel-mode><remote-user-tunnel>tunnel.2</remote-user-tunnel>

and that seemed to create a valid GP Gateway, including the items you have called out as an issue, like interface, tunnel mode, tunnel interface, etc.

 

I hope this helps to give you more insight and a path forward.

Help the community: "Like" helpful comments, and click "Accept as Solution" if you found your answer 🙂

L2 Linker

Jimmy,

thank you very much. This is the solution. But as you can see from my original post I was aware of the other path (to gateway-N) and I had said
"I have tried creating MY-GP-GATEWAY first and MY-GP-GATEWAY-N second, and vice versa, no luck".
So I was doing something wrong for sure.
Anyway, I copied your API calls with my parameters and it created the gateway the way I wanted it.
Again thanks for your help.

 

L5 Sessionator

Hi @RogerMccarrick, apologies for mis-reading your post, but very glad that it is working now! 🙂

Help the community: "Like" helpful comments, and click "Accept as Solution" if you found your answer 🙂
  • 1 accepted solution
  • 3146 Views
  • 5 replies
  • 0 Likes
Like what you see?

Show your appreciation!

Click Like if a post is helpful to you or if you just want to show your support.

Click Accept as Solution to acknowledge that the answer to your question has been provided.

The button appears next to the replies on topics you’ve started. The member who gave the solution and all future visitors to this topic will appreciate it!

These simple actions take just seconds of your time, but go a long way in showing appreciation for community members and the LIVEcommunity as a whole!

The LIVEcommunity thanks you for your participation!