For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

rahvee's avatar
rahvee
Icon for Cirrus rankCirrus
3 years ago

In BIGREST, how to simultaneously add & remove ssl client profile on virtual server?

I am able to add an ssl client profile to a virtual server via

f5_session.create(f"/mgmt/tm/ltm/virtual/{rest_format(virtual_server_path_str)}/profiles", data)
I am able to remove an ssl client profile via
delete_path = f"/mgmt/tm/ltm/virtual/{rest_format(virtual_server_path_str)}/profiles/{rest_format(profile_path_str)}"
f5_session.delete(delete_path)
But I need to simultaneously add & delete, because I am replacing the ssl client profile that has "default for SNI" enabled. In order to have exactly one profile with this flag enabled, the add & remove must both occur atomically.
 
I've tried every variation I can think of, using `modify()` or `save()`, but still haven't got it right yet. Here is my latest attempt:
 
virtual_server_results = f5_session.load("/mgmt/tm/ltm/virtual")
client_ssl_profile_results = f5_session.load("/mgmt/tm/ltm/profile/client-ssl")

remove_client_ssl_profile = None # Start as None
append_client_ssl_profile = None

for client_ssl_profile in client_ssl_profile_results:
if client_ssl_profile.properties['fullPath'] == '/Common/ssl_client_profile_SNI_1':
assert remove_client_ssl_profile is None # Guarantees I cannot set it more than once
remove_client_ssl_profile = client_ssl_profile
if client_ssl_profile.properties['fullPath'] == '/Common/ssl_client_profile_SNI_2':
assert append_client_ssl_profile is None
append_client_ssl_profile = client_ssl_profile

assert remove_client_ssl_profile is not None # Guarantees I set it at least once
assert append_client_ssl_profile is not None

# Since `remove_client_ssl_profile` and `append_client_ssl_profile` started as None,
# and I have `assert remove_client_ssl_profile is None` guaranteeing it will never be set
# more than once, and I have `assert remove_client_ssl_profile is not None` guaratneeing it
# was set at least once, I am guaranteed to have found exactly one match for each.
# No more, no less.

for virtual_server in virtual_server_results:
# `profilesReference / link` always has the form:
# 'https://localhost/mgmt/tm/ltm/virtual/~Common~LDAP-Intermediate/profiles?ver=14.1.4.6'
# So strip the leading 'https://localhost' from it
strip_len = len('https://localhost')
v_s_profiles_link = virtual_server.properties["profilesReference"]['link'][strip_len:]
v_s_profiles = f5_session.load(v_s_profiles_link)
for v_s_profile in v_s_profiles:
if v_s_profile.properties['fullPath'] == remove_client_ssl_profile.properties['fullPath']:
v_s_profiles.remove(v_s_profile)
v_s_profiles.append(append_client_ssl_profile)
f5_session.save(virtual_server)

This latest attempt doesn't throw any errors, but the virtual server doesn't get changed, so it's not working.

Thanks for any help.

3 Replies

    • rahvee's avatar
      rahvee
      Icon for Cirrus rankCirrus

      Here, I added comments to the code to explain that. But that was never the important part. The important part is to figure out which object I need to modify by which method, in order to make both changes occur in a single operation.

  • So far, the only solution I can find (so this is what I'm currently coding up) is: I have to actually delete all the ssl profiles from the virtual server, saving the `sniDefault` one for last. Then I have to add them all back in, with the new `sniDefault` one first.