"}},"component({\"componentId\":\"custom.widget.Consent_Blackbar\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[],\"name\":\"TagPage\",\"props\":{},\"url\":\"https://community.f5.com\"}}})":{"__typename":"ComponentRenderResult","html":""}},"component({\"componentId\":\"custom.widget.Tag_Manager_Helper\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[],\"name\":\"TagPage\",\"props\":{},\"url\":\"https://community.f5.com\"}}})":{"__typename":"ComponentRenderResult","html":" "}},"tagFollowsForNodes({\"nodeIds\":\"category:Articles\",\"tagText\":\"BIG-IP\"})":[{"__typename":"TagFollowForNodeResponse","coreNode":{"__ref":"Category:category:Articles"},"follow":null}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/OverflowNav\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/OverflowNav-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageView/MessageViewInline\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageView/MessageViewInline-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/Pager/PagerLoadMore\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMore-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageUnreadCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageUnreadCount-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageViewCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageViewCount-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"components/kudos/KudosCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/kudos/KudosCount-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRepliesCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRepliesCount-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1728320186000"}],"cachedText({\"lastModified\":\"1728320186000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1728320186000"}]},"CachedAsset:pages-1737020476965":{"__typename":"CachedAsset","id":"pages-1737020476965","value":[{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1737020476965,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Former Member","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"dd-MMM-yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":"en","possibleValues":["en-US"]}},"deleted":false},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"CachedAsset:theme:customTheme1-1737020476533":{"__typename":"CachedAsset","id":"theme:customTheme1-1737020476533","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["custom"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"JimmyPackets-512-1702592938213.png","imageLastModified":"1702592945815","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"f5_logo_fix-1704824537976.svg","imageLastModified":"1704824540697","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1600px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_PAGE_CONTENT","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"5px","borderRadius":"5px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"14px","paddingXHero":"42px","fontStyle":"NORMAL","fontWeight":"400","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-400)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-400-h), var(--lia-bs-gray-400-s), calc(var(--lia-bs-gray-400-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-400-h), var(--lia-bs-gray-400-s), calc(var(--lia-bs-gray-400-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-300)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-300-h), var(--lia-bs-gray-300-s), calc(var(--lia-bs-gray-300-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-300-h), var(--lia-bs-gray-300-s), calc(var(--lia-bs-gray-300-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"NONE","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.06)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.15)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.15)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-primary)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","forumColor":"#0C5C8D","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#62C026","blogColor":"#730015","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#C20025","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#F3704B","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#EE4B5B","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#491B62","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#949494","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0C5C8D","secondary":"#333333","bodyText":"#222222","bodyBg":"#F5F5F5","info":"#1D9CD3","success":"#62C026","warning":"#FFD651","danger":"#C20025","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#C20025","#081B85","#009639","#B3C6D7","#7CC0EB","#F29A36"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Inter","fontStyle":"NORMAL","fontWeight":"600","h1FontSize":"30px","h2FontSize":"25px","h3FontSize":"20px","h4FontSize":"18px","h5FontSize":"16px","h6FontSize":"16px","lineHeight":"1.2","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":null,"h2FontWeight":null,"h3FontWeight":null,"h4FontWeight":null,"h5FontWeight":null,"h6FontWeight":null,"__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":null,"imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"14px","defaultMessageHeaderMarginBottom":"10px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"14px","specialMessageHeaderMarginBottom":"10px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Atkinson Hyperlegible","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.3","fontSizeBase":"15px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"13px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1728320186000","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1728320186000","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:text:en_US-pages/tags/TagPage-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-pages/tags/TagPage-1728320186000","value":{"tagPageTitle":"Tag:\"{tagName}\" | {communityTitle}","tagPageForNodeTitle":"Tag:\"{tagName}\" in \"{title}\" | {communityTitle}","name":"Tags Page","tag":"Tag: {tagName}"},"localOverride":false},"Category:category:top":{"__typename":"Category","id":"category:top","entityType":"CATEGORY","displayId":"top","nodeType":"category","depth":0,"title":"Top","shortTitle":"Top"},"Category:category:Articles":{"__typename":"Category","id":"category:Articles","entityType":"CATEGORY","displayId":"Articles","nodeType":"category","depth":1,"title":"Articles","description":"HowTo's and Community News.","avatar":null,"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:top"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:zihoc95639"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"tagPolicies":{"__typename":"TagPolicies","canSubscribeTagOnNode":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.labels.action.corenode.subscribe_labels.allow.accessDenied","key":"error.lithium.policies.labels.action.corenode.subscribe_labels.allow.accessDenied","args":[]}},"canManageTagDashboard":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.labels.action.corenode.admin_labels.allow.accessDenied","key":"error.lithium.policies.labels.action.corenode.admin_labels.allow.accessDenied","args":[]}}}},"CachedAsset:quilt:f5.prod:pages/tags/TagPage:category:Articles-1737020474670":{"__typename":"CachedAsset","id":"quilt:f5.prod:pages/tags/TagPage:category:Articles-1737020474670","value":{"id":"TagPage","container":{"id":"Common","headerProps":{"removeComponents":["community.widget.bannerWidget"],"__typename":"QuiltContainerSectionProps"},"items":[{"id":"tag-header-widget","layout":"ONE_COLUMN","bgColor":"var(--lia-bs-white)","showBorder":"BOTTOM","sectionEditLevel":"LOCKED","columnMap":{"main":[{"id":"tags.widget.TagsHeaderWidget","__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"},"__typename":"OneColumnQuiltSection"},{"id":"messages-list-for-tag-widget","layout":"ONE_COLUMN","columnMap":{"main":[{"id":"messages.widget.messageListForNodeByRecentActivityWidget","props":{"viewVariant":{"type":"inline","props":{"useUnreadCount":true,"useViewCount":true,"useAuthorLogin":true,"clampBodyLines":3,"useAvatar":true,"useBoardIcon":false,"useKudosCount":true,"usePreviewMedia":true,"useTags":false,"useNode":true,"useNodeLink":true,"useTextBody":true,"truncateBodyLength":-1,"useBody":true,"useRepliesCount":true,"useSolvedBadge":true,"timeStampType":"conversation.lastPostingActivityTime","useMessageTimeLink":true,"clampSubjectLines":2}},"panelType":"divider","useTitle":false,"hideIfEmpty":false,"pagerVariant":{"type":"loadMore"},"style":"list","showTabs":true,"tabItemMap":{"default":{"mostRecent":true,"mostRecentUserContent":false,"newest":false},"additional":{"mostKudoed":true,"mostViewed":true,"mostReplies":false,"noReplies":false,"noSolutions":false,"solutions":false}}},"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"},"__typename":"OneColumnQuiltSection"}],"__typename":"QuiltContainer"},"__typename":"Quilt"},"localOverride":false},"CachedAsset:quiltWrapper:f5.prod:Common:1737020422786":{"__typename":"CachedAsset","id":"quiltWrapper:f5.prod:Common:1737020422786","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":"header.jpg","backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"LEFT_CENTER","lastModified":"1702932449000","__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.Beta_MetaNav","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"community.widget.navbarWidget","props":{"showUserName":false,"showRegisterLink":true,"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","linkFontWeight":"700","controllerHighlightColor":"hsla(30, 100%, 50%)","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkFontSize":"15px","linkBoxShadowHover":"none","backgroundOpacity":0.4,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","linkTextBorderBottom":"none","hamburgerColor":"var(--lia-nav-controller-icon-color)","brandLogoHeight":"48px","linkLetterSpacing":"normal","linkBgHoverColor":"transparent","collapseMenuDividerOpacity":0.16,"paddingBottom":"10px","dropdownPaddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"0","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","linkJustifyContent":"center","linkColor":"var(--lia-bs-primary)","collapseMenuDividerBg":"var(--lia-nav-link-color)","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-primary)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid #0C5C8D","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","linkPaddingX":"10px","paddingTop":"10px","linkPaddingY":"5px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkBgColor":"transparent","linkDropdownPaddingY":"9px","controllerIconColor":"#0C5C8D","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"#0C5C8D"},"links":{"sideLinks":[],"mainLinks":[{"children":[{"linkType":"INTERNAL","id":"migrated-link-1","params":{"boardId":"TechnicalForum","categoryId":"Forums"},"routeName":"ForumBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-2","params":{"boardId":"WaterCooler","categoryId":"Forums"},"routeName":"ForumBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-0","params":{"categoryId":"Forums"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-4","params":{"boardId":"codeshare","categoryId":"CrowdSRC"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-5","params":{"boardId":"communityarticles","categoryId":"CrowdSRC"},"routeName":"TkbBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-3","params":{"categoryId":"CrowdSRC"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-7","params":{"boardId":"TechnicalArticles","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"article-series","params":{"boardId":"article-series","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"security-insights","params":{"boardId":"security-insights","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-8","params":{"boardId":"DevCentralNews","categoryId":"Articles"},"routeName":"TkbBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-6","params":{"categoryId":"Articles"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-10","params":{"categoryId":"CommunityGroups"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"migrated-link-11","params":{"categoryId":"F5-Groups"},"routeName":"CategoryPage"}],"linkType":"INTERNAL","id":"migrated-link-9","params":{"categoryId":"GroupsCategory"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"migrated-link-12","params":{"boardId":"Events","categoryId":"top"},"routeName":"EventBoardPage"},{"children":[],"linkType":"INTERNAL","id":"migrated-link-13","params":{"boardId":"Suggestions","categoryId":"top"},"routeName":"IdeaBoardPage"}]},"className":"QuiltComponent_lia-component-edit-mode__lQ9Z6","showSearchIcon":false},"__typename":"QuiltComponent"},{"id":"community.widget.bannerWidget","props":{"backgroundColor":"transparent","visualEffects":{"showBottomBorder":false},"backgroundImageProps":{"backgroundSize":"COVER","backgroundPosition":"CENTER_CENTER","backgroundRepeat":"NO_REPEAT"},"fontColor":"#222222"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"var(--lia-bs-primary)","linkHighlightColor":"#FFFFFF","visualEffects":{"showBottomBorder":false},"backgroundOpacity":60,"linkTextColor":"#FFFFFF"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"var(--lia-bs-body-color)","items":[{"id":"custom.widget.Beta_Footer","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Tag_Manager_Helper","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Consent_Blackbar","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1728320186000","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.Beta_MetaNav-en-1737020491748":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_MetaNav-en-1737020491748","value":{"component":{"id":"custom.widget.Beta_MetaNav","template":{"id":"Beta_MetaNav","markupLanguage":"HANDLEBARS","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"dynamicByCoreNode":false,"description":"MetaNav menu at the top of every page.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Beta_MetaNav","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"dynamicByCoreNode":false,"description":"MetaNav menu at the top of every page.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Beta_Footer-en-1737020491748":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_Footer-en-1737020491748","value":{"component":{"id":"custom.widget.Beta_Footer","template":{"id":"Beta_Footer","markupLanguage":"HANDLEBARS","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"dynamicByCoreNode":false,"description":"DevCentral´s custom footer.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Beta_Footer","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"dynamicByCoreNode":false,"description":"DevCentral´s custom footer.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Tag_Manager_Helper-en-1737020491748":{"__typename":"CachedAsset","id":"component:custom.widget.Tag_Manager_Helper-en-1737020491748","value":{"component":{"id":"custom.widget.Tag_Manager_Helper","template":{"id":"Tag_Manager_Helper","markupLanguage":"HANDLEBARS","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"dynamicByCoreNode":false,"description":"Helper widget to inject Tag Manager scripts into head element","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Tag_Manager_Helper","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"dynamicByCoreNode":false,"description":"Helper widget to inject Tag Manager scripts into head element","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Consent_Blackbar-en-1737020491748":{"__typename":"CachedAsset","id":"component:custom.widget.Consent_Blackbar-en-1737020491748","value":{"component":{"id":"custom.widget.Consent_Blackbar","template":{"id":"Consent_Blackbar","markupLanguage":"HTML","style":null,"texts":null,"defaults":{"config":{"applicablePages":[],"dynamicByCoreNode":false,"description":"","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Consent_Blackbar","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"TEXTHTML","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"dynamicByCoreNode":false,"description":"","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1728320186000","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagsHeaderWidget-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagsHeaderWidget-1728320186000","value":{"tag":"{tagName}","topicsCount":"{count} {count, plural, one {Topic} other {Topics}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageListForNodeByRecentActivityWidget-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageListForNodeByRecentActivityWidget-1728320186000","value":{"title@userScope:other":"Recent Content","title@userScope:self":"Contributions","title@board:FORUM@userScope:other":"Recent Discussions","title@board:BLOG@userScope:other":"Recent Blogs","emptyDescription":"No content to show","MessageListForNodeByRecentActivityWidgetEditor.nodeScope.label":"Scope","title@instance:1706288370055":"Content Feed","title@instance:1704319314827":"Blog Feed","title@instance:1704317906837":"Content Feed","title@instance:1702668293472":"Community Feed","title@instance:1704320290851":"My Contributions","title@instance:1703720491809":"Forum Feed","title@instance:1703028709746":"Group Content Feed","title@instance:VTsglH":"Content Feed"},"localOverride":false},"Category:category:Forums":{"__typename":"Category","id":"category:Forums","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Forum:board:TechnicalForum":{"__typename":"Forum","id":"board:TechnicalForum","forumPolicies":{"__typename":"ForumPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Forum:board:WaterCooler":{"__typename":"Forum","id":"board:WaterCooler","forumPolicies":{"__typename":"ForumPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:TechnicalArticles":{"__typename":"Tkb","id":"board:TechnicalArticles","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"displayId":"TechnicalArticles","nodeType":"board","conversationStyle":"TKB","title":"Technical Articles","shortTitle":"Technical Articles","parent":{"__ref":"Category:category:Articles"}},"Tkb:board:DevCentralNews":{"__typename":"Tkb","id":"board:DevCentralNews","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:GroupsCategory":{"__typename":"Category","id":"category:GroupsCategory","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:F5-Groups":{"__typename":"Category","id":"category:F5-Groups","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:CommunityGroups":{"__typename":"Category","id":"category:CommunityGroups","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Occasion:board:Events":{"__typename":"Occasion","id":"board:Events","boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"occasionPolicies":{"__typename":"OccasionPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Idea:board:Suggestions":{"__typename":"Idea","id":"board:Suggestions","boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"ideaPolicies":{"__typename":"IdeaPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:CrowdSRC":{"__typename":"Category","id":"category:CrowdSRC","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:codeshare":{"__typename":"Tkb","id":"board:codeshare","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:communityarticles":{"__typename":"Tkb","id":"board:communityarticles","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:security-insights":{"__typename":"Tkb","id":"board:security-insights","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:article-series":{"__typename":"Tkb","id":"board:article-series","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Conversation:conversation:334264":{"__typename":"Conversation","id":"conversation:334264","topic":{"__typename":"TkbTopicMessage","uid":334264},"lastPostingActivityTime":"2025-01-03T08:31:03.630-08:00","solved":false},"User:user:303102":{"__typename":"User","uid":303102,"login":"Ulises_Alonso","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0zMDMxMDItNnNGUVZV?image-coordinates=90%2C0%2C517%2C427"},"id":"user:303102"},"TkbTopicMessage:message:334264":{"__typename":"TkbTopicMessage","subject":"VMware vSphere to OpenShift Virtualization Migration with F5 BIG-IP","conversation":{"__ref":"Conversation:conversation:334264"},"id":"message:334264","revisionNum":12,"uid":334264,"depth":0,"board":{"__ref":"Tkb:board:TechnicalArticles"},"author":{"__ref":"User:user:303102"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" Guidance for your migration plans of BIG-IP from VMware vSphere to Red Hat OpenShift Virtualization ","introduction":"","metrics":{"__typename":"MessageMetrics","views":599},"postTime":"2024-09-13T12:35:30.222-07:00","lastPublishTime":"2025-01-03T08:31:03.630-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Introduction \n OpenShift Virtualization [1] [2] is Red Hat’s offering for KubeVirt virtualization, a solid virtualization platform for VM workloads. In turn, KubeVirt is based on the KVM/QEMU projects. VMs running in OpenShift Virtualization can be plugged into the POD network and/or in external networks, being able to replace a VMware platform. \n This article has an attached guide (PDF) that shows how to move workloads and BIG-IP Virtual Edition (VE) instances from VMware with vSphere networking to OpenShift Virtualization. This guide is aligned with the OpenShift Virtualization Reference Implementation Guide and the OpenShift Migration Toolkit for Virtualization. The latter facilitates the migration of application VMs. \n Overview of the guide \n The guide is composed of the following sections: \n \n Overview of the migration process \n Network considerations \n Preparatory works \n Migration procedure \n Additional information \n \n The guide is meant to be self-contained and includes all the details needed. In https://github.com/f5devcentral/f5-bd-openshift-virt-migration/tree/main you will find sample manifests to be used alongside the guide. \n Note that migrating a BIG-IP VE from VMware to OpenShift Virtualization doesn’t require any additional licenses. The existing licenses can be re-used. \n Note also that OpenShift Virtualization requires the Q35 machine type, which is supported starting with BIG-IP versions 15.1.0, 16.1.5, and 17.1.1. Check this link for details. \n Final remarks and next steps \n OpenShift Virtualization provides a strong foundation to host both VM and container workloads, thus unifying the platform for all applications and ultimately simplifying the infrastructure. \n Download the attached PDF to see the guide. This guide is a living document, and we expect to update it with improved content. We are looking forward to your questions and comments on the guide. ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"1934","kudosSumWeight":5,"repliesCount":2,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:283971":{"__typename":"Conversation","id":"conversation:283971","topic":{"__typename":"TkbTopicMessage","uid":283971},"lastPostingActivityTime":"2024-12-10T05:00:00.030-08:00","solved":false},"User:user:214133":{"__typename":"User","uid":214133,"login":"Hardeep_Kaur","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/m_assets/avatars/custom/Frankenstack_02-1706129554890.svg"},"id":"user:214133"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTE2MDdpMzQzRkI0NEVGQTdBMTBBNg?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTE2MDdpMzQzRkI0NEVGQTdBMTBBNg?revision=8","title":"0151T0000040JicQAE.png","associationType":"BODY","width":1996,"height":579,"altText":"0151T0000040JicQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTQzOTNpRDlFNEY2NEMxNzUwMkYyMA?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTQzOTNpRDlFNEY2NEMxNzUwMkYyMA?revision=8","title":"0151T0000040Qc7QAE.png","associationType":"BODY","width":1280,"height":610,"altText":"0151T0000040Qc7QAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTI1M2k0QjREQjE0MDNGNzM0QjhB?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTI1M2k0QjREQjE0MDNGNzM0QjhB?revision=8","title":"0151T0000040JidQAE.png","associationType":"BODY","width":1798,"height":915,"altText":"0151T0000040JidQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDYzMWk5MUM4QkE3MEQ4NDE3RkQz?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDYzMWk5MUM4QkE3MEQ4NDE3RkQz?revision=8","title":"0151T0000040JihQAE.png","associationType":"BODY","width":1881,"height":1747,"altText":"0151T0000040JihQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTg2MGkxQUZDQzY2MjJFMUY2QzVG?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTg2MGkxQUZDQzY2MjJFMUY2QzVG?revision=8","title":"0151T0000040JimQAE.png","associationType":"BODY","width":1820,"height":1258,"altText":"0151T0000040JimQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtODc1MGk5MTFFRkE4QkE2RDY5MDc5?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtODc1MGk5MTFFRkE4QkE2RDY5MDc5?revision=8","title":"0151T0000040JinQAE.png","associationType":"BODY","width":1895,"height":1495,"altText":"0151T0000040JinQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTA4NjNpNTYyM0FBN0Q5MDgyQzhCRQ?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTA4NjNpNTYyM0FBN0Q5MDgyQzhCRQ?revision=8","title":"0151T0000040JirQAE.png","associationType":"BODY","width":1558,"height":1408,"altText":"0151T0000040JirQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDIzMWk1NThDNzNERUVDNDM2QUYy?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDIzMWk1NThDNzNERUVDNDM2QUYy?revision=8","title":"0151T0000040JiiQAE.png","associationType":"BODY","width":2092,"height":1413,"altText":"0151T0000040JiiQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtTnpNQ2xh?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtTnpNQ2xh?revision=8","title":"irule.png","associationType":"BODY","width":1449,"height":1027,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNTYxNGlFQTIzRjk4OTQ3MDM5OThC?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNTYxNGlFQTIzRjk4OTQ3MDM5OThC?revision=8","title":"0151T0000040JisQAE.png","associationType":"BODY","width":1276,"height":656,"altText":"0151T0000040JisQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNzI1OGk2QTM3NzVDNjM1QkVBQUZD?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNzI1OGk2QTM3NzVDNjM1QkVBQUZD?revision=8","title":"0151T0000040JitQAE.png","associationType":"BODY","width":1555,"height":386,"altText":"0151T0000040JitQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMjAyaTI3MkExOEM2MjAwMjI3NUM?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMjAyaTI3MkExOEM2MjAwMjI3NUM?revision=8","title":"0151T0000040JioQAE.png","associationType":"BODY","width":1435,"height":597,"altText":"0151T0000040JioQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMzYzOGk1QTA0REIyQ0M5NjIzQjBC?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMzYzOGk1QTA0REIyQ0M5NjIzQjBC?revision=8","title":"0151T0000040N2LQAU.png","associationType":"BODY","width":2222,"height":1018,"altText":"0151T0000040N2LQAU.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtODYzM2lGNzREQzI1Q0Q5M0VBMEI2?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtODYzM2lGNzREQzI1Q0Q5M0VBMEI2?revision=8","title":"0151T0000040MvyQAE.png","associationType":"BODY","width":2099,"height":419,"altText":"0151T0000040MvyQAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNjY2N2k1RTYxRDE4QjE3OTZCNkE1?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNjY2N2k1RTYxRDE4QjE3OTZCNkE1?revision=8","title":"0151T0000040MwDQAU.png","associationType":"BODY","width":1236,"height":331,"altText":"0151T0000040MwDQAU.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDYzNGlDRDdBN0JFQzVEOEMwODBB?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDYzNGlDRDdBN0JFQzVEOEMwODBB?revision=8","title":"0151T0000040Jj1QAE.png","associationType":"BODY","width":718,"height":450,"altText":"0151T0000040Jj1QAE.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDE1aTRDODQ3ODk3QjU5REQ2Njc?revision=8\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDE1aTRDODQ3ODk3QjU5REQ2Njc?revision=8","title":"0151T0000040MwNQAU.png","associationType":"BODY","width":2797,"height":1392,"altText":"0151T0000040MwNQAU.png"},"TkbTopicMessage:message:283971":{"__typename":"TkbTopicMessage","subject":"APM Configuration to Support Duo MFA using iRule","conversation":{"__ref":"Conversation:conversation:283971"},"id":"message:283971","revisionNum":8,"uid":283971,"depth":0,"board":{"__ref":"Tkb:board:TechnicalArticles"},"author":{"__ref":"User:user:214133"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":17227},"postTime":"2021-03-03T08:35:12.000-08:00","lastPublishTime":"2024-12-10T05:00:00.030-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Overview \n BIG-IP APM has supported Duo as an MFA provider for a long time with RADIUS-based integration. Recently, Duo has added support for Universal Prompt that uses Open ID Connect (OIDC) protocol to provide two-factor authentication. To integrate APM as an OIDC client and resource server, and Duo as an Identity Provider (IdP), Duo requires the user’s logon name and custom parameters to be sent for Authentication and Token request. \n This guide describes the configuration required on APM to enable Duo MFA integration using an iRule. iRules addresses the custom parameter challenges by generating the needed custom values and saving them in session variables, which the OAuth Client agent then uses to perform MFA with Duo. This integration procedure is supported on BIG-IP versions 13.1, 14.1x, 15.1x, and 16.x. \n To integrate Duo MFA with APM, complete the following tasks: \n 1. Choose deployment type: Per-request or Per-session \n 2. Configure credentials and policies for MFA on the DUO web portal \n 3. Create OAuth objects on the BIG-IP system \n 4. Configure the iRule \n 5. Create the appropriate access policy/policies on the BIG-IP system \n 6. Apply policy/policies and iRule to the APM virtual server \n Choose deployment type \n APM supports two different types of policies for performing authentication functions. \n \n Per-session policies: Per-session policies provide authentication and authorization functions that occur only at the beginning of a user’s session. These policies are compatible with most APM use cases such as VPN, Webtop portal, Remote Desktop, federation IdP, etc. \n Per-request policies: Per-request policies provide dynamic authentication and authorization functionality that may occur at any time during a user’s session, such as step-up authentication or auditing functions only for certain resources. These policies are only compatible with Identity Aware Proxy and Web Access Management use cases and cannot be used with VPN or webtop portals. \n \n This guide contains information about setting up both policy types. \n Prerequisites \n Ensure the BIG-IP system has DNS and internet connectivity to contact Duo directly for validating the user's OAuth tokens. \n Configure credentials and policies for MFA on Duo web portal \n Before you can protect your F5 BIG-IP APM Web application with Duo, you will first need to sign up for a Duo account. \n 1. Log in to the Duo Admin Panel and navigate to Applications. \n 2. Click Protect an application. \n Figure 1: Duo Admin Panel – Protect an Application \n 3. Locate the entry for F5 BIG-IP APM Web in the applications list and click Protect to get the Client ID, Client secret, and API hostname. You will need this information to configure objects on APM. \n Figure 2: Duo Admin Panel – F5 BIG-IP APM Web \n 4. As DUO is used as a secondary authentication factor, the user’s logon name is sent along with the authentication request. Depending on your security policy, you may want to pre-provision users in Duo, or you may allow them to self-provision to set their preferred authentication type when they first log on. \n To add users to the Duo system, navigate to the Dashboard page and click the Add New... -> Add User button. A Duo username should match the user's primary authentication username. Refer to the https://duo.com/docs/enrolling-users link for the different methods of user enrollment. \n Refer to Duo Universal Prompt for additional information on Duo’s two-factor authentication. \n Create OAuth objects on the BIG-IP system \n Create a JSON web key \n When APM is configured to act as an OAuth client or resource server, it uses JSON web keys (JWKs) to validate the JSON web tokens it receives from Duo. \n To create a JSON web key: \n 1. On the Main tab, select Access > Federation > JSON Web Token > Key Configuration. \n The Key Configuration screen opens. \n 2. To add a new key configuration, click Create. \n 3. In the ID and Shared Secret fields, enter the Client ID and Client Secret values respectively obtained from Duo when protecting the application. \n 4. In the Type list, select the cryptographic algorithm used to sign the JSON web key. \n Figure 3: Key Configuration screen \n 5. Click Save. \n Create a JSON web token \n As an OAuth client or resource server, APM validates the JSON web tokens (JWT) it receives from Duo. \n To create a JSON web token: \n 1. On the Main tab, select Access > Federation > JSON Web Token > Token Configuration. \n The Token Configuration screen opens. \n 2. To add a new token configuration, click Create. \n 3. In the Issuer field, enter the API hostname value obtained from Duo when protecting the application. \n 4. In the Signing Algorithms area, select from the Available list and populate the Allowed and Blocked lists. \n 5. In the Keys (JWK) area, select the previously configured JSON web key in the allowed list of keys. \n Figure 4: Token Configuration screen \n 6. Click Save. \n Configure Duo as an OAuth provider \n APM uses the OAuth provider settings to get URIs on the external OAuth authorization server for JWT web tokens. \n To configure an OAuth provider: \n 1. On the Main tab, select Access > Federation > OAuth Client / Resource Server > Provider. \n The Provider screen opens. \n 2. To add a provider, click Create. \n 3. In the Name field, type a name for the provider. \n 4. From the Type list, select Custom. \n 5. For Token Configuration (JWT), select a configuration from the list. \n 6. In the Authentication URI field, type the URI on the provider where APM should redirect the user for authentication. The hostname is the same as the API hostname in the Duo application. \n 7. In the Token URI field, type the URI on the provider where APM can get a token. The hostname is the same as the API hostname in the Duo application. \n Figure 5: OAuth Provider screen \n 8. Click Finished. \n Configure Duo server for APM \n The OAuth Server settings specify the OAuth provider and role that Access Policy Manager (APM) plays with that provider. It also sets the Client ID, Client Secret, and Client’s SSL certificates that APM uses to communicate with the provider. \n To configure a Duo server: \n 1. On the Main tab, select Access > Federation > OAuth Client / Resource Server > OAuth Server. \n The OAuth Server screen opens. \n 2. To add a server, click Create. \n 3. In the Name field, type a name for the Duo server. \n 4. From the Mode list, select how you want the APM to be configured. \n 5. From the Type list, select Custom. \n 6. From the OAuth Provider list, select the Duo provider. \n 7. From the DNS Resolver list, select a DNS resolver (or click the plus (+) icon, create a DNS resolver, and then select it). \n 8. In the Token Validation Interval field, type a number. \n In a per-request policy subroutine configured to validate the token, the subroutine repeats at this interval or the expiry time of the access token, whichever is shorter. \n 9. In the Client Settings area, paste the Client ID and Client secret you obtained from Duo when protecting the application. \n 10. From the Client's ServerSSL Profile Name, select a server SSL profile. \n Figure 6: OAuth Server screen \n 11. Click Finished. \n Configure an auth-redirect-request and a token-request \n Requests specify the HTTP method, parameters, and headers to use for the specific type of request. An auth-redirect-request tells Duo where to redirect the end-user, and a token-request accesses the authorization server for obtaining an access token. \n To configure an auth-redirect-request: \n 1. On the Main tab, select Access > Federation > OAuth Client / Resource Server > Request. \n The Request screen opens. \n 2. To add a request, click Create. \n 3. In the Name field, type a name for the request. \n 4. For the HTTP Method, select GET. \n 5. For the Type, select auth-redirect-request. \n 6. As shown in Figure 7, specify the list of GET parameters to be sent: \n \n request parameter with value depending on the type of policy \n For per-request policy: %{subsession.custom.jwt_duo} \n For per-session policy: %{session.custom.jwt_duo} \n client_id parameter with type client-id \n response_type parameter with type response-type \n \n Figure 7: Request screen with auth-redirect-request (Use “subsession.custom…” for Per-request or “session.custom…” for Per-session) \n 7. Click Finished. \n To configure a token-request: \n 1. On the Main tab, select Access > Federation > OAuth Client / Resource Server > Request. \n The Request screen opens. \n 2. To add a request, click Create. \n 3. In the Name field, type a name for the request. \n 4. For the HTTP Method, select POST. \n 5. For the Type, select token-request. \n 6. As shown in Figure 8, specify the list of POST parameters to be sent: \n \n client_assertion parameter with value depending on the type of policy \n For per-request policy: %{subsession.custom.jwt_duo_token} \n For per-session policy: %{session.custom.jwt_duo_token} \n client_assertion_type parameter with value urn:ietf:params:oauth:client-assertion-type:jwt-bearer \n grant_type parameter with type grant-type \n redirect_uri parameter with type redirect-uri \n \n Figure 8: Request screen with token-request (Use “subsession.custom…” for Per-request or “session.custom…” for Per-session) \n 7. Click Finished. \n Configure the iRule \n iRules gives you the ability to customize and manage your network traffic. Configure an iRule that creates the required sub-session variables and usernames for Duo integration. \n Note: This iRule has sections for both per-request and per-session policies and can be used for either type of deployment. \n To configure an iRule: \n 1. On the Main tab, click Local Traffic > iRules. \n 2. To create an iRules, click Create. \n 3. In the Name field, type a name for the iRule. \n 4. Copy the sample code given below and paste it in the Definition field. \n Replace the following variables with values specific to the Duo application: \n \n <Duo Client ID> in the getClientId function with Duo Application ID. \n <Duo API Hostname> in the createJwtToken function with API Hostname. For example, https://api-duohostname.com/oauth/v1/token. \n <JSON Web Key> in the getJwkName function with the configured JSON web key. \n \n Note: The iRule ID here is set as JWT_CREATE. You can rename the ID as desired. You specify this ID in the iRule Event agent in Visual Policy Editor. \n Note: The variables used in the below example are global, which may affect your performance. Refer to the K95240202: Understanding iRule variable scope article for further information on global variables, and determine if you use a local variable for your implementation. \n when ACCESS_POLICY_AGENT_EVENT {\n if { [ACCESS::policy agent_id] eq \"JWT_CREATE\" } {\n set duo_uname [ACCESS::session data get \"session.logon.last.username\"]\n\n # Inline logic for creating JWT\n set header \"{\\\"alg\\\":\\\"HS512\\\",\\\"typ\\\":\\\"JWT\\\"}\"\n set exp [expr {[clock seconds] + 900}]\n set client_id \"<Duo Client ID>\"\n\n set redirect_uri \"https://[ACCESS::session data get session.server.network.name]/oauth/client/redirect\"\n set payload \"{\\\"response_type\\\": \\\"code\\\",\\\"scope\\\":\\\"openid\\\",\\\"exp\\\":${exp},\\\"client_id\\\":\\\"${client_id}\\\",\\\"redirect_uri\\\":\\\"${redirect_uri}\\\",\\\"duo_uname\\\":\\\"${duo_uname}\\\"}\"\n\n set jwt_duo [ACCESS::oauth sign -header $header -payload $payload -alg HS512 -key \"<JSON Web Key>\"]\n ACCESS::session data set session.custom.jwt_duo $jwt_duo\n\n # JWT Token creation\n set aud \"<Duo API Hostname>\"\n set jti [string range [clock seconds] 0 31]\n set token_payload \"{\\\"sub\\\": \\\"${client_id}\\\",\\\"iss\\\":\\\"${client_id}\\\",\\\"aud\\\":\\\"${aud}\\\",\\\"exp\\\":${exp},\\\"jti\\\":\\\"${jti}\\\"}\"\n\n set jwt_duo_token [ACCESS::oauth sign -header $header -payload $token_payload -alg HS512 -key \"<JSON Web Key>\"]\n ACCESS::session data set session.custom.jwt_duo_token $jwt_duo_token\n }\n}\n\nwhen ACCESS_PER_REQUEST_AGENT_EVENT {\n if { [ACCESS::perflow get perflow.irule_agent_id] eq \"JWT_CREATE\" } {\n set duo_uname [ACCESS::session data get \"session.logon.last.username\"]\n\n set header \"{\\\"alg\\\":\\\"HS512\\\",\\\"typ\\\":\\\"JWT\\\"}\"\n set exp [expr {[clock seconds] + 900}]\n set client_id \"<Duo Client ID>\"\n\n set redirect_uri \"https://[ACCESS::session data get session.server.network.name]/oauth/client/redirect\"\n set payload \"{\\\"response_type\\\": \\\"code\\\",\\\"scope\\\":\\\"openid\\\",\\\"exp\\\":${exp},\\\"client_id\\\":\\\"${client_id}\\\",\\\"redirect_uri\\\":\\\"${redirect_uri}\\\",\\\"duo_uname\\\":\\\"${duo_uname}\\\"}\"\n\n set jwt_duo [ACCESS::oauth sign -header $header -payload $payload -alg HS512 -key \"<JSON Web Key>\"]\n ACCESS::perflow set perflow.custom $jwt_duo\n\n # JWT Token creation\n set aud \"<Duo API Hostname>\"\n set jti [string range [clock seconds] 0 31]\n set token_payload \"{\\\"sub\\\": \\\"${client_id}\\\",\\\"iss\\\":\\\"${client_id}\\\",\\\"aud\\\":\\\"${aud}\\\",\\\"exp\\\":${exp},\\\"jti\\\":\\\"${jti}\\\"}\"\n\n set jwt_duo_token [ACCESS::oauth sign -header $header -payload $token_payload -alg HS512 -key \"<JSON Web Key>\"]\n ACCESS::perflow set perflow.scratchpad $jwt_duo_token\n }\n} \n Note: iRule updated 11/27/2024 to eliminate CMP demotion. \n \n Figure 9: iRule screen \n 5. Click Finished. \n Create the appropriate access policy/policies on the BIG-IP system \n Per-request policy \n Skip this section for a per-session type deployment \n The per-request policy is used to perform secondary authentication with Duo. Configure the access policies through the access menu, using the Visual Policy Editor. The per-request access policy must have a subroutine with an iRule Event, Variable Assign, and an OAuth Client agent that requests authorization and tokens from an OAuth server. You may use other per-request policy items such as URL branching or Client Type to call Duo only for certain target URIs. \n Figure 10 shows a subroutine named duosubroutine in the per-request policy that handles Duo MFA authentication. \n Figure 10: Per-request policy in Visual Policy Editor \n Configuring the iRule Event agent \n The iRule Event agent specifies the iRule ID to be executed for Duo integration. In the ID field, type the iRule ID as configured in the iRule. \n Figure 11: iRule Event agent in Visual Policy Editor \n Configuring the Variable Assign agent \n The Variable Assign agent specifies the variables for token and redirect requests and assigns a value for Duo MFA in a subroutine. This is required only for per-request type deployment. Add sub-session variables as custom variables and assign their custom Tcl expressions as shown in Figure 12. \n \n subsession.custom.jwt_duo_token = return [mcget {perflow.scratchpad}] \n subsession.custom.jwt_duo = return [mcget {perflow.custom}] \n \n Figure 12: Variable Assign agent in Visual Policy Editor \n Configuring the OAuth Client agent \n An OAuth Client agent requests authorization and tokens from the Duo server. Specify OAuth parameters as shown in Figure 13. \n \n In the Server list, select the Duo server to which the OAuth client directs requests. \n In the Authentication Redirect Request list, select the auth-redirect-request configured earlier. \n In the Token Request list, select the token-request configured earlier. \n Some deployments may not need the additional information provided by OpenID Connect. You could, in that case, disable it. \n \n Figure 13: OAuth Client agent in Visual Policy Editor \n Per-session policy \n Configure the Per Session policy as appropriate for your chosen deployment type. \n \n Per-request: The per-session policy must contain at least one logon page to set the username variable in the user’s session. Preferably it should also perform some type of primary authentication. This validated username is used later in the per-request policy. \n Per-session: The per-session policy is used for all authentication. A per-request policy is not used. \n \n Figures 14a and 14b show a per-session policy that runs when a client initiates a session. Depending on the actions you include in the access policy, it can authenticate the user and perform actions that populate session variables with data for use throughout the session. \n Figure 14a: Per-session policy in Visual Policy Editor performs both primary authentication and Duo authentication (for per-session use case) \n Figure 14b: Per-session policy in Visual Policy Editor performs primary authentication only (for per-request use case) \n Apply policy/policies and iRule to the APM virtual server \n Finally, apply the per-request policy, per-session policy, and iRule to the APM virtual server. You assign iRules as a resource to the virtual server that users connect. Configure the virtual server’s default pool to the protected local web resource. \n Apply policy/policies to the virtual server \n Per-request policy \n To attach policies to the virtual server: \n 1. On the Main tab, click Local Traffic > Virtual Servers. \n 2. Select the Virtual Server. \n 3. In the Access Policy section, select the policy you created. \n 4. Click Finished. \n Figure 15: Access Policy section in Virtual Server (per-request policy) \n Per-session policy \n Figure 16 shows the Access Policy section in Virtual Server when the per-session policy is deployed. \n Figure 16: Access Policy section in Virtual Server (per-session policy) \n Apply iRule to the virtual server \n To attach the iRule to the virtual server: \n 1. On the Main tab, click Local Traffic > Virtual Servers. \n 2. Select the Virtual Server. \n 3. Select the Resources tab. \n 4. Click Manage in the iRules section. \n 5. Select an iRule from the Available list and add it to the Enabled list. \n 6. Click Finished. ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"17974","kudosSumWeight":10,"repliesCount":51,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wx","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTE2MDdpMzQzRkI0NEVGQTdBMTBBNg?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wy","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTQzOTNpRDlFNEY2NEMxNzUwMkYyMA?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wz","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTI1M2k0QjREQjE0MDNGNzM0QjhB?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3w0","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDYzMWk5MUM4QkE3MEQ4NDE3RkQz?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3w1","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTg2MGkxQUZDQzY2MjJFMUY2QzVG?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3w2","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtODc1MGk5MTFFRkE4QkE2RDY5MDc5?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3w3","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMTA4NjNpNTYyM0FBN0Q5MDgyQzhCRQ?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3w4","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDIzMWk1NThDNzNERUVDNDM2QUYy?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3w5","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtTnpNQ2xh?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wxMA","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNTYxNGlFQTIzRjk4OTQ3MDM5OThC?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wxMQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNzI1OGk2QTM3NzVDNjM1QkVBQUZD?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wxMg","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMjAyaTI3MkExOEM2MjAwMjI3NUM?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wxMw","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtMzYzOGk1QTA0REIyQ0M5NjIzQjBC?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wxNA","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtODYzM2lGNzREQzI1Q0Q5M0VBMEI2?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wxNQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNjY2N2k1RTYxRDE4QjE3OTZCNkE1?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wxNg","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDYzNGlDRDdBN0JFQzVEOEMwODBB?revision=8\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wxNw","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODM5NzEtNDE1aTRDODQ3ODk3QjU5REQ2Njc?revision=8\"}"}}],"totalCount":17,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:332000":{"__typename":"Conversation","id":"conversation:332000","topic":{"__typename":"TkbTopicMessage","uid":332000},"lastPostingActivityTime":"2024-11-23T11:54:21.170-08:00","solved":false},"User:user:74420":{"__typename":"User","uid":74420,"login":"Doddy_ZUHRI","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/m_assets/avatars/default/avatar-6.svg"},"id":"user:74420"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtQ2xSNXJ5?revision=10\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtQ2xSNXJ5?revision=10","title":"image.png","associationType":"BODY","width":580,"height":540,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtdDZkeG5i?revision=10\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtdDZkeG5i?revision=10","title":"image.png","associationType":"BODY","width":720,"height":375,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtT0lNcnNm?revision=10\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtT0lNcnNm?revision=10","title":"image.png","associationType":"BODY","width":1770,"height":668,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtdWw4R0hR?revision=10\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtdWw4R0hR?revision=10","title":"image.png","associationType":"BODY","width":1056,"height":962,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtbkFYUmV4?revision=10\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtbkFYUmV4?revision=10","title":"image.png","associationType":"BODY","width":1924,"height":904,"altText":""},"TkbTopicMessage:message:332000":{"__typename":"TkbTopicMessage","subject":"Use Fully Qualified Domain Name (FQDN) for GSLB Pool Member with F5 DNS","conversation":{"__ref":"Conversation:conversation:332000"},"id":"message:332000","revisionNum":10,"uid":332000,"depth":0,"board":{"__ref":"Tkb:board:TechnicalArticles"},"author":{"__ref":"User:user:74420"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":405},"postTime":"2024-10-04T05:00:00.027-07:00","lastPublishTime":"2024-10-04T05:00:00.027-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Normally, we define a specific IP (and port) to be used as GSLB pool member. This article provides a custom configuration to be able to use Fully Qualified Domain Name (FQDN) as GSLB pool member--with all GSLB features like health-check monitoring, load balancing method, persistence, etc. \n Despite GSLB as a mechanism to distribute traffic across datacenters having reached years of age, it has not become less relevant this recent years. The fact that internet infrastructure still rely heavily on DNS technology means GSLB is continuously used due to is lightweight nature and smooth integration. \n When using F5 DNS as GSLB solution, usually we are dealing with LTM and its VS as GSLB server and pool member respectively. Sometimes, we will add a non-LTM node as a generic server to provide inter-DC load balancing capability. Either way, we will end up with a pair of IP and port to represent the application, in which we sent a health-check against. \n Due to the trend of public cloud and CDN, there is a need to use FQDN as GSLB pool member (instead of IP and port pair). Some of us may immediately think of using a CNAME-type GSLB pool to accommodate this. However, there is a limitation in which BIG-IP requires a CNAME-type GSLB pool to use a wideIP-type pool member, in which we will end up with an IP and port pair (again!) \n \n We can use \"static target\", but there is \"side-effect\" where the pool member will always consider available (which then triggers the question why we need to use GSLB in the first place!). \n Additionally, F5 BIG-IP TMUI accepts FQDN input when we configure GSLB server and pool member. However, it will immediately translate to IP based on configured DNS. Thus, this is not the solution we are looking for \n \n Now this is where F5’s BIG-IP power (a.k.a programmability) comes into play. \n \n Enter the realm of customization... \n We all love customization, but at the same time do not want that to be overly complicated so that life becomes harder on day-2 🙃. Thus, the key is to use some customization, but simple enough to avoid unnecessary complication. Here is one idea to solve our FQDN as GSLB pool problem above \n \n The customized configuration object includes \n 1. External health-check monitor: \n \n Dynamically resolve DNS to translate FQDN into IP address \n Perform health-check monitoring against current IP address \n Result is used to determine GSLB pool member availability status \n \n 2. DNS iRules: \n \n Check #1: Checks if GSLB pool attached to wideIP contains only FQDN-type member (e.g. other pool referring to LTM VS is also attached to the wideIP)\n \n If false, do nothing (let DNS response refer to LTM VS) \n Otherwise, perform check #2 \n \n \n Check #2: Checks current health-check status of requested domain name\n \n If FQDN is up, modify DNS response to return current IP of FQDN \n Otherwise, perform fallback action as requirement (e.g. return empty response, return static IP, use fallback pool, etc.) \n \n \n \n 3. Internal Datagroup: \n \n Store current IP of FQDN, updated according to health-check interval \n Datagroup record value contains current IP if health-check success. Otherwise, the value contains empty data \n \n Here are some of the codes, where configured; wideIP is gslb.test.com, while GSLB pool member FQDN is arcadia.f5poc.id \n 1. External health-check monitor config \n gtm monitor external gslb_external_monitor { \n defaults-from external \n destination *:* interval 10 \n probe-timeout 5 \n run /Common/gslb_external_monitor_script \n timeout 120 \n #define FQDN here \n user-defined fqdn arcadia.f5poc.id \n} \n External health-check monitor script \n #!/bin/sh\npidfile=\"/var/run/$MONITOR_NAME.$1..$2.pid\"\nif [ -f $pidfile ]\nthen\n kill -9 -`cat $pidfile` > /dev/null 2>&1\nfi\necho \"$$\" > $pidfile\n# Obtain current IP for the FQDN\nresolv=`dig +short ${fqdn}`\n# The actual monitoring action here\ncurl -fIs -k https://${fqdn}/ --resolve ${fqdn}:443:${resolv} | grep -i HTTP 2>&1 > /dev/null\nstatus=$?\nif [ $status -eq 0 ]\nthen\n# Actions when health-check success \n rm -f $pidfile\n tmsh modify ltm data-group internal fqdn { records replace-all-with { $fqdn { data $resolv } } }\n echo \"sending monitor to ${fqdn} ${resolv} with result OK\" | logger -p local0.info\n echo \"up\"\nelse\n# Actions when health-check fails \n tmsh modify ltm data-group internal fqdn { records replace-all-with { $fqdn { } } }\n echo \"sending monitor to ${fqdn} ${resolv} with result NOK\" | logger -p local0.info\nfi\nrm -f $pidfile\n \n 2. DNS iRules \n when DNS_REQUEST { \n set qname [DNS::question name] \n # Obtain current IP for the FQDN\n set currentip [class match -value $qname equals fqdn] \n} \nwhen DNS_RESPONSE { \n set rname [getfield [lindex [split [DNS::answer]] 4] \"\\}\" 1 ]\n #Check if return is IP address of specially encoded FQDN IP, 10.10.10.10 in this example \n if {$rname eq \"10.10.10.10\" }{ \n #Response is only from pool with external monitor, meaning no other pool is attached to wideIP \n if {$currentip ne \"\"}{ \n #Current FQDN health-check success \n DNS::answer clear \n # Use current IP to construct DNS answer section\n DNS::answer insert \"[DNS::question name]. 123 [DNS::question class] [DNS::question type] $currentip\" \n } else { \n #Current FQDN health-check failed #Define action to be performed here \n DNS::answer clear \n } \n } \n}\n \n 3. Internal Datagroup \n ltm data-group internal fqdn {\n records {\n # Define FQDN as record name\n arcadia.f5poc.id {\n # Record data contains IP, where this will be continuously updated by external monitoring script\n data 158.140.176.219\n }\n }\n type string\n}\n \n *GSLB virtual server configuration \n \n \n Some testing \n \n The resolve will follow whichever current IP address for the FQDN. If a returning CNAME response is required, you can do so by modifying DNS irules above. \n The logic and code are open to any improvement, so leave your suggestions in the comments if you have any. Thanks! ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"6158","kudosSumWeight":1,"repliesCount":1,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wx","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtQ2xSNXJ5?revision=10\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wy","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtdDZkeG5i?revision=10\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wz","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtT0lNcnNm?revision=10\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3w0","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtdWw4R0hR?revision=10\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3w1","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzIwMDAtbkFYUmV4?revision=10\"}"}}],"totalCount":5,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:282829":{"__typename":"Conversation","id":"conversation:282829","topic":{"__typename":"TkbTopicMessage","uid":282829},"lastPostingActivityTime":"2024-11-16T02:50:35.651-08:00","solved":false},"User:user:106220":{"__typename":"User","uid":106220,"login":"Joe_Pruitt","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0xMDYyMjAtUU1TTFdB?image-coordinates=0%2C0%2C1000%2C1000"},"id":"user:106220"},"TkbTopicMessage:message:282829":{"__typename":"TkbTopicMessage","subject":"iRule Editor - System Config Editing","conversation":{"__ref":"Conversation:conversation:282829"},"id":"message:282829","revisionNum":1,"uid":282829,"depth":0,"board":{"__ref":"Tkb:board:TechnicalArticles"},"author":{"__ref":"User:user:106220"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":397},"postTime":"2010-01-15T08:17:00.000-08:00","lastPublishTime":"2010-01-15T08:17:00.000-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" In the latest release of the iRule Editor v 0.10.1, I added several new features. This tutorial will walk through System Level Configuration editing allowing you to work with your bigip.conf and bigip_base.conf files without having to open a terminal session to the BIG-IP. \n Usage: \n\n\n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"301","kudosSumWeight":0,"repliesCount":7,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:335263":{"__typename":"Conversation","id":"conversation:335263","topic":{"__typename":"TkbTopicMessage","uid":335263},"lastPostingActivityTime":"2024-11-15T00:53:08.338-08:00","solved":false},"User:user:51154":{"__typename":"User","uid":51154,"login":"JRahm","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS01MTE1NC1uYzdSVFk?image-coordinates=0%2C0%2C1067%2C1067"},"id":"user:51154"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzUyNjMtRk5ZdWdU?revision=3\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzUyNjMtRk5ZdWdU?revision=3","title":"synack.png","associationType":"BODY","width":906,"height":904,"altText":""},"TkbTopicMessage:message:335263":{"__typename":"TkbTopicMessage","subject":"Happy 20th Birthday, BIG-IP TMOS!","conversation":{"__ref":"Conversation:conversation:335263"},"id":"message:335263","revisionNum":3,"uid":335263,"depth":0,"board":{"__ref":"Tkb:board:TechnicalArticles"},"author":{"__ref":"User:user:51154"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":538},"postTime":"2024-10-16T15:34:52.393-07:00","lastPublishTime":"2024-10-16T15:34:52.393-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" I wasn’t in the waiting room with the F5 family, ears and eyes perked for the release announcement of BIG-IP version 9.0. I was a customer back in 2004, working on a government contract at Scott AFB, Illinois. I shared ownership of the F5 infrastructure, pairs of BIG-IPs running version 4.5 on Dell PowerEdge 2250 servers with one other guy. But maybe a month or two before the official first release of TMOS, my F5 account manager dropped off some shiny new hardware. And it was legit purpose-built and snazzy, not some garage-style hacked Frankenstein of COTS parts like the earlier stuff. And you wonder why we chose Dell servers! \n Anyway, I was a hard-core network engineer at this time, with very little exposure to anything above layer four, and even there, my understanding was limited to ports and ACLs and maybe a little high-level clarity around transport protocols. But application protocols? Nah. No idea. So with this new hardware and an entirely new full-proxy architecture (what’s a proxy, again?) I was overwhelmed. And honestly, I was frustrated with it for the first few days because I didn’t know what I didn’t know and so I struggled to figure out what to do with it, even to replicate my half-proxy configuration in the “new way”. \n \n But I’m a curious person. Given enough time and caffeine, I can usually get to the bottom of a problem, at least well enough to arrive at a workable solution. And so I did. My typical approach to anything is to make it work, make it work better, make it work reliably better, then finally make it work reliably and more performantly better. And the beauty here with this new TMOS system is that I was armed with a treasure trove of new toys. The short list I dug into during my beta trial, which lasted for a couple of weeks: \n \n The concept of a profile. When you support a few applications, this is no big deal. When you support hundreds, being able to macro configuration snippets within your application and across applications was revolutionary. Not just for the final solution, but also for setting up and executing your test plans. \n iRules. Yes, technically they existed in 4.x, but they were very limited in scope. With TMOS, F5 introduced the Tcl-based and F5 extended live-traffic scripting environment that unleashed tremendous power and flexibility for network and application teams. I dabbled with this, and thought I understood exactly how useful this was. More on this a little later. \n A host operating system. I was a router, switch, and firewall guy. Nothing I worked on had this capability. I mean, a linux system built in to my networking device? YES!!! Two things I never knew I always needed during my trial: 1) tcpdump ON BOX. Seriously--mind blown; and 2) perl scripting against config and snmp. Yeah, I know, I laugh about perl now. But 20 years ago, it was the cats pajamas. \n \n A fortunate job change \n Shortly after my trial was over, I interviewed for an accepted a job offer from a major rental car company that was looking to hire an engineer to redesign their application load balancing infrastructure and select the next gear purchase for the effort. We evaluated Cisco, Nortel/Alteon, Radware, and F5 on my recommendation. With our team’s resident architect we drafted the rubric with which we’d evaluate all the products, and whereas there were some layer two performance issues in some packet sizes that were arguably less than real-world, the BIG-IP blew away the competitors across the board. Particularly, though, in configurability and instrumentation. Tcpdump on box was such a game-changer for us. \n Did we have issues with TMOS version 9? For sure. My first year with TMOS was also TMOS's first year. Bugs are going to happen with any release, but a brand new thing is guaranteed. But F5 support was awesome, and we worked through all the issues in due time. Anyway, I want to share three wins in my first year with TMOS. \n Win #1 \n Our first production rollout was in the internet space, on BIG-IP version 9.0.5. That’s right, a .0 release. TMOS was a brand new baby, and we had great confidence throughout our testing. During our maintenance, once we flipped over the BIG-IPs, our rental transaction monitors all turned red and the scripted rental process had increased by 50%! Not good. “What is this F5 stuff? Send it back!!” But it was new, and we knew we had a gem here. We took packet captures on box, of course, then rolled back and took more packet captures, this time through taps because our old stuff didn’t have tcpdump on box. \n This is where Jason started to really learn about the implications of both a full proxy architecture and the TCP protocol. It turns our our application servers had a highly-tuned TCP stack on them specific to the characteristics of the rental application. We didn’t know this, of course. But since we implemented a proxy that terminates clients at the BIG-IP and starts a new session to the servers, all those customizations for WAN traffic were lost. Once we built a TCP profile specifically for the rental application servers and tested it under WAN emulation, we not only reached parity with the prior performance but beat it by 10%. Huzzah! Go BIG-IP custom protocol stack configuration! \n Win #2 \n For the next internal project, I had to rearchitect the terminal server farm. We had over 700 servers in two datacenters supporting over 60,000 thin clients around the world for rental terminals. Any failures meant paper tickets and unhappy staff and customers. One thing that was problematic with the existing solution is that sometimes clients would detach and upon reconnect would connect directly to the server, which skewed the load balancers view of the world and frequently overloaded some servers to the point all sessions on that server would hang until metrics (but usually angry staff) would notify. Remember my iRules comment earlier on differentiators? Well, iRules architect David Hansen happened to be a community hero and was very helpful to me in the DevCentral forums and really opened my eyes to the art of possible with iRules. He was able to take the RDP session token that was being returned by the client, read it, translate it from its Microsoft encoding format, and then forward the session on to the correct server in the backend so that all sessions continued to be accounted for in our load balancing tier. This was formative for me as a technologist and as a member of the DevCentral community. \n Win #3 \n 2004-2005 was the era before security patching was as visible a responsibility as it is today, but even then we had a process and concerns when there were obstacles. We had an internal application that had a plugin for the web tier that managed all the sessions to the app tier, and this plugin was no longer supported. We were almost a year behind on system and application patches because we had no replacement for this. Enter, again, iRules. I was able to rebuild the logic of the plugin in an iRule that IIRC wasn’t more than 30 lines. So the benefits ended up not only being a solution to that problem, but the ability to remove that web tier altogether, saving on equipment, power, and complexity costs. \n And that was just the beginning... \n TMOS was mature upon arrival, but it got better every year. iControl added REST-based API access; clustered multi-processing introduced tremendous performance gains; TMOS got virtualized, and all the home-lab technologists shouted with joy; a plugin architecture allowed for product modules like ASM and APM; solutions that began as iRules like AFM and SSLO became products. It’s crazy how much innovation has taken place on this platform! \n The introduction of TMOS didn’t just introduce me to applications and programmability. It did that and I’m grateful, but it did so much more. It unlocked in me that fanboy level that fans of sports teams, video game platforms, Taylor Swift, etc, experience. It helped me build an online community at DevCentral, long before I was an employee. \n Happy 20th Birthday, TMOS! We celebrate and salute you! ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"8094","kudosSumWeight":10,"repliesCount":1,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wx","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzUyNjMtRk5ZdWdU?revision=3\"}"}}],"totalCount":1,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:333503":{"__typename":"Conversation","id":"conversation:333503","topic":{"__typename":"TkbTopicMessage","uid":333503},"lastPostingActivityTime":"2024-11-14T03:25:55.807-08:00","solved":false},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzM1MDMtcVdlcE5C?revision=10\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzM1MDMtcVdlcE5C?revision=10","title":"converge.jpg","associationType":"TEASER","width":610,"height":402,"altText":""},"TkbTopicMessage:message:333503":{"__typename":"TkbTopicMessage","subject":"BIG-IP VE in Red Hat OpenShift Virtualization","conversation":{"__ref":"Conversation:conversation:333503"},"id":"message:333503","revisionNum":10,"uid":333503,"depth":0,"board":{"__ref":"Tkb:board:TechnicalArticles"},"author":{"__ref":"User:user:303102"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" \n ","introduction":"","metrics":{"__typename":"MessageMetrics","views":513},"postTime":"2024-09-04T05:00:00.030-07:00","lastPublishTime":"2024-10-07T09:00:37.435-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" \n Overview \n Running BIG-IP VE in OpenShift Virtualization allows for VM and modern apps/Kubernetes to convergence, simplifying management and operations. OpenShift Virtualization is Red Hat's enterprise-ready KubeVirt offering which uses the well established QEMU+KVM Linux virtualization layers under the hood. OpenShift Virtualization/KubeVirt provides a Kubernetes declarative interface. Configuring & running BIG-IP VE in OpenShift Virtualization is very much the same as in any other hypervisor or cloud provider. The initial BIG-IP configuration is done likewise using cloud-init and Declarative Onboarding. On the other hand, VM and platform configurations are specific of the environment. This article focuses in these latter. All the best practice recommendations in this article are aligned with the OpenShift Virtualization Reference Implementation Guide which is a recommended reading. Update: the manifests referenced in this article can be found in https://github.com/f5devcentral/f5-bd-openshift-virt-migration/tree/main/bigip-vsphere-networking These contain the Kubernetes manifests to setup a BIG-IP HA pair with the best practices. In the next sections it will be covered each of these highlighting the most important aspects of these as well as including relevant links for additional information. Note: In order to use BIG-IP VE in OpenShift Virtualization it is required to use versions starting with 15.1.10, 16.1.5 and 17.1.1. \n Platform configuration \n The base installation of OpenShift Virtualization is done following these steps. After this, it is best practice to additionally setup CPU Manager to guarantee resource allocation and also setup Topology Manager to set a single single-numa-node policy which guarantees all VM resources are in the same NUMA domain. This configuration is applied to machineConfigPool with the label custom-kubelet: cpumanager-enabled as it can be seen in the official configuration example. These configurations are done with a single KubeletConfig manifest which can be found in the attached bigip-platform-manifests.zip. OpenShift Virtualization/KubeVirt uses QEMU/KVM under the hood and typically the QEMU Guest Agent is used to allow low level operations on the VMs. In the case of a F5 BIG-IP VE appliance these operations are not supported and therefore the agent is not needed. \n VirtualMachine configuration \n The attached bigip-vm-manifests.zip contains recommended VirtualMachine configurations for a typical HA pair with network attachments with typical external, internal, ha and management interfaces. This zip file also contains the DataVolume manifests which specify where the qcow2 files of the VE will be residing. This sample manifest downloads the qcow2 file from a web server, other methods are supported. Please accommodate these to your needs. Next it will be described what are the key sections: \n \n podAntiAffinity rules to avoid two BIG-IPs of the same HA-pair to run in the same node \n \n spec: \n runStrategy: Always\n template: \n metadata: \n labels: \n f5type: bigip-ve \n bigip-unit: unit-1 \n spec: \n affinity:\n podAntiAffinity:\n requiredDuringSchedulingIgnoredDuringExecution:\n - labelSelector:\n matchExpressions:\n - key: \"bigip-unit\"\n operator: In\n values:\n - unit-2\n topologyKey: \"kubernetes.io/hostname\"\n \n Resource allocation: CPU, memory and network queues domain: \n cpu: \n sockets: 1 \n # Adjust cores to the desired number of vCPUs \n cores: 4 \n threads: 1 \n dedicatedCpuPlacement: true \n resources: \n # memory must be 2Gi per core at least \n requests: \n memory: 8Gi \n limits: \n memory: 8Gi \ndevices: \n networkInterfaceMultiqueue: true\n \n \n \n Annotations to hint the CPU scheduler to enable low latency to the BIG-IPs. See this link for details. apiVersion: kubevirt.io/v1\nKind: VirtualMachine \nmetadata: \n name: bigip1 \n namespace: f5-bigip \n labels: \n f5type: bigip-ve \n annotations: \n k8s.v1.cni.cncf.io/networks: bigip1-mgmt,bigip1-ha,bigip1-ext,bigip1-int\n cpu-quota.crio.io: disable\n cpu-load-balancing.crio.io: disable \n irq-load-balancing.crio.io: disable \n \n Network configuration \n This guide follows the OpenShift Virtualization Reference Implementation Guide recommendation of using NodeNetworkConfigurationPolicy with type OVS bridge and NetworkAttachmentDefinitions with type ovn-k8s-cni-overlay and topology localnet. Alternatively, It is also fully supported by BIG-IP VE to use any other VirtIO based networking. \n The ovn-k8s-cni-overlay+localnet networking provides access to the physical network and features micro-segmentation by means of using tags instead of IP addresses as well as better visibility of the traffic. This feature needs to be enabled on the Operator and configured using the MultiNetworkPolicy resource. \n It is important to remark that access to the physical network is provided by ovn-k8s-cni-overlay with access ports to the VMs, that is: VLAN trunking or tagging cannot be exposed to VMs. If VLAN trunking or tagging was used previously, then the interfaces and tagging configured in the VLANs will need to be modified. BIG-IP VE can have a total of 28 NICs[1]. Considering one NIC for management, this means that BIG-IP VE can be connected to 27 VLANs with this network type. Note: at time of this writing the ID 1492337 requires to set the MTU manually at cloud-init stage. This is done in the provided VirtualMachine manifests. Search for \"ndal mtu\" keywords in these. \n [1] https://clouddocs.f5.com/cloud/public/v1/kvm/kvm_setup.html#virtual-machine-network-interfaces \n Final remarks and next steps \n In future articles we will describe further how to expand further the possibilities of OpenShift Virtualization by covering the following topics: \n \n Migrating BIG-IP VE from VMware to OpenShift Virtualization \n Using BIG-IP VE and CIS connected to a POD network \n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"6129","kudosSumWeight":4,"repliesCount":3,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wx","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzM1MDMtcVdlcE5C?revision=10\"}"}}],"totalCount":1,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:335424":{"__typename":"Conversation","id":"conversation:335424","topic":{"__typename":"TkbTopicMessage","uid":335424},"lastPostingActivityTime":"2024-10-24T05:00:00.050-07:00","solved":false},"User:user:419147":{"__typename":"User","uid":419147,"login":"aconley","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS00MTkxNDctME4wMDV0?image-coordinates=0%2C0%2C2400%2C2400"},"id":"user:419147"},"TkbTopicMessage:message:335424":{"__typename":"TkbTopicMessage","subject":"Load Balancing TCP TLS Encrypted Syslog Messages","conversation":{"__ref":"Conversation:conversation:335424"},"id":"message:335424","revisionNum":2,"uid":335424,"depth":0,"board":{"__ref":"Tkb:board:TechnicalArticles"},"author":{"__ref":"User:user:419147"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":390},"postTime":"2024-10-24T05:00:00.050-07:00","lastPublishTime":"2024-10-24T05:00:00.050-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Syslog messages sent via TCP are not always evenly distributed among backend syslog servers because multiple syslog messages can be sent in a single TCP connection. This article utilizes the F5 BIG-IP Generic Message Routing Framework (MRF) to evenly distribute syslog messages among backend syslog pool members. This solution also uses TLS to protect the confidentiality of the syslog messages. \n This article is based off the work done by Mark Lloyd in this DevCentral Technical Article: A Simple One-way Generic MRF Implementation to load balance syslog message. In his article, Mark explains how to setup Generic Message Routing Framework (MRF) to distribute syslog messages sent via TCP to a pool of syslog servers. This article adds the necessary configuration to TLS encrypt, decrypt, and re-encrypt the messages. \n This was tested on BIG-IP version 17.1.0.1. \n The first step is to define the message routing protocol. The difference between the default protocol (genericmsg) is the field no-response must be configured to yes if this is a one-way stream. Otherwise, the server side will allocate buffers for return traffic that will cause severe free memory depletion. Note: The message-terminator is set to \"%0a\", this represents a newline character in hex and is used to separate the syslog messages. This value can be changed if a different delineator is required. \n ltm message-routing generic protocol simple_syslog_protocol {\n app-service none\n defaults-from genericmsg\n description none\n disable-parser no\n max-egress-buffer 32768\n max-message-size 32768\n message-terminator %0a\n no-response yes\n} \n An iRule must be configured on both the Virtual Server and Generic Transport Config. This iRule must be linked as a profile in both the virtual server and the generic transport configuration. \n ltm rule mrf_simple {\nwhen CLIENT_ACCEPTED {\n GENERICMESSAGE::peer name \"[IP::local_addr]:[TCP::local_port]_[IP::remote_addr]:[TCP::remote_port]\"\n }\n \nwhen SERVER_CONNECTED {\n GENERICMESSAGE::peer name \"[IP::local_addr]:[TCP::local_port]_[IP::remote_addr]:[TCP::remote_port]\"\n \n }\n} \n The next item to configure is the generic transport config. The generic transport config has the generic protocol configured along with the iRule to setup the server-side peers. A server-side SSL profile is also configured here to TLS encrypt the traffic to the backend syslog servers. \n ltm message-routing generic transport-config simple_syslog_tcp_tc {\n ip-protocol tcp\n profiles {\n serverssl-insecure-compatible { }\n simple_syslog_protocol { }\n tcp { }\n }\n rules {\n mrf_simple\n }\n} \n Nodes are defined for the backend Syslog servers. \n ltm node 10.1.20.201 {\n address 10.1.20.201\n}\nltm node 10.1.20.202 {\n address 10.1.20.202\n} \n A pool is created containing the nodes. \n ltm pool syslog_pool {\n members {\n 10.1.20.201:514 {\n address 10.1.20.201\n }\n 10.1.20.202:514 {\n address 10.1.20.202\n }\n }\n} \n The next step is to create the generic message routing peer. This peer is used to identify the pool of syslog servers that the syslog messages will be routed to. \n ltm message-routing generic peer simple_syslog_peer {\n pool syslog_pool\n transport-config simple_syslog_tcp_tc\n} \n Now that the peer is defined, a generic route can be created to send traffic to the peer. \n ltm message-routing generic route simple_syslog_route {\n peers {\n simple_syslog_peer\n }\n} \n A generic router is configured with the generic route. \n ltm message-routing generic router simple_syslog_router {\n app-service none\n defaults-from messagerouter\n description none\n ignore-client-port no\n max-pending-bytes 23768\n max-pending-messages 64\n mirror disabled\n mirrored-message-sweeper-interval 1000\n routes {\n simple_syslog_route\n }\n traffic-group traffic-group-1\n use-local-connection yes\n} \n A client-ssl profile is configured to associate the certificates to the Virtual Server. \n ltm profile client-ssl syslog-ng_client {\n app-service none\n cert-key-chain {\n syslog-ng-new_f5demos_ca_0 {\n cert syslog-ng-new\n chain f5demos_ca\n key syslog-ng-new\n }\n }\n defaults-from clientssl\n inherit-ca-certkeychain true\n inherit-certkeychain false\n} \n A virtual server is created to receive incoming TLS-encrypted TCP syslog messages. \n ltm virtual mrftest_simple {\n creation-time 2024-10-08:09:37:52\n destination 10.1.10.101:514\n ip-protocol tcp\n last-modified-time 2024-10-08:13:55:49\n mask 255.255.255.255\n profiles {\n simple_syslog_protocol { }\n simple_syslog_router { }\n syslog-ng_client {\n context clientside\n }\n tcp { }\n }\n rules {\n mrf_simple\n }\n serverssl-use-sni disabled\n source 0.0.0.0/0\n source-address-translation {\n type automap\n }\n translate-address enabled\n translate-port enabled\n vs-index 2\n} \n Conclusion \n This example is from a use case where a single syslog client was sending to a TCP load balancer. The load balancer was not evenly distributing the load among the backend servers because multiple messages were being sent as part of a single TCP connection. This solution utilizes a generic Message Routing Framework to evenly distribute TCP syslog messages. TLS encryption is also used on the client to load balancer connection as well as the load balancer to backend server connection to protect the confidentiality of the syslog messages. ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"5656","kudosSumWeight":0,"repliesCount":0,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:275636":{"__typename":"Conversation","id":"conversation:275636","topic":{"__typename":"TkbTopicMessage","uid":275636},"lastPostingActivityTime":"2024-10-14T09:51:23.719-07:00","solved":false},"User:user:86049":{"__typename":"User","uid":86049,"login":"Colin_Walker_12","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/m_assets/avatars/default/avatar-4.svg"},"id":"user:86049"},"TkbTopicMessage:message:275636":{"__typename":"TkbTopicMessage","subject":"iRules 101 - #12 - The Session Command","conversation":{"__ref":"Conversation:conversation:275636"},"id":"message:275636","revisionNum":2,"uid":275636,"depth":0,"board":{"__ref":"Tkb:board:TechnicalArticles"},"author":{"__ref":"User:user:86049"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":3456},"postTime":"2008-03-18T08:28:00.000-07:00","lastPublishTime":"2024-10-14T09:51:23.719-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" One of the things that makes iRules so incredibly powerful is the fact that it is a true scripting language, or at least based on one. The fact that they give you the tools that TCL brings to the table - regular expressions, string functions, even things as simple as storing, manipulating and recalling variable data - sets iRules apart from the rest of the crowd. It also makes it possible to do some pretty impressive things with connection data and massaging/directing it the way you want it. Other articles in the series: \n \n Getting Started with iRules: Intro to Programming with Tcl | DevCentral \n Getting Started with iRules: Control Structures & Operators | DevCentral \n Getting Started with iRules: Variables | DevCentral \n Getting Started with iRules: Directing Traffic | DevCentral \n Getting Started with iRules: Events & Priorities | DevCentral \n Intermediate iRules: catch | DevCentral \n Intermediate iRules: Data-Groups | DevCentral \n Getting Started with iRules: Logging & Comments | DevCentral \n Advanced iRules: Regular Expressions | DevCentral \n Getting Started with iRules: Events & Priorities | DevCentral \n iRules 101 - #12 - The Session Command | DevCentral \n Intermediate iRules: Nested Conditionals | DevCentral \n Intermediate iRules: Handling Strings | DevCentral \n Intermediate iRules: Handling Lists | DevCentral \n Advanced iRules: Scan | DevCentral \n Advanced iRules: Binary Scan | DevCentral \n \n Sometimes, though, a simple variable won't do. You've likely heard of global variables in one of the earlier 101 series and read the warning there, and are looking for another option. So here you are, you have some data you need to store, which needs to persist across multiple connections. You need it to be efficient and fast, and you don't want to have to do a whole lot of complex management of a data structure. One of the many ways that you can store and access information in your iRule fits all of these things perfectly, little known as it may be. For this scenario I'd recommend the usage of the session command. \n There are three main permutations of the session command that you'll be using when storing and referencing data within the session table. These are: \n \n session add: Stores user's data under the specified key for the specified persistence mode \n session lookup: Returns user data previously stored using session add \n session delete: Removes user data previously stored using session add \n \n A simple example of adding some information to the session table would look like: \n when CLIENTSSL_CLIENTCERT {\n set ssl_cert [SSL::cert 0]\n session add ssl $ssl_cert 90\n}\n \n By using the session add command, you can manually place a specific piece of data into the LTM's session table. You can then look it up later, by unique key, with the session lookup command and use the data in a different section of your iRule, or in another connection all together. This can be helpful in different situations where data needs to be passed between iRules or events that it might not normally be when using a simple variable. Such as mining SSL data from the connection events, as below: \n when CLIENTSSL_CLIENTCERT {\n # Set results in the session so they are available to other events\n session add ssl [SSL::sessionid] [list [X509::issuer] [X509::subject] [X509::version]] 180\n}\n\nwhen HTTP_REQUEST {\n # Retrieve certificate information from the session\n set sslList [session lookup ssl [SSL::sessionid]]\n set issuer [lindex sslList 0]\n set subject [lindex sslList 1]\n set version [lindex sslList 2]\n}\n \n Because the session table is optimized and designed to handle every connection that comes into the LTM, it's very efficient and can handle quite a large number of items. Also note that, as above, you can pass structured information such as TCL Lists into the session table and they will remain intact. Keep in mind, though, that there is currently no way to count the number of entries in the table with a certain key, so you'll have to build all of your own processing logic for now, where necessary. \n It's also important to note that there is more than one session table. If you look at the above example, you'll see that before we listed any key or data to be stored, we used the command session add ssl. Note the \"ssl\" portion of this command. This is a reference to which session table the data will be stored in. For our purposes here there are effectively two session tables: ssl, and uie. Be sure you're accessing the same one in your session lookup section as you are in your session add section, or you'll never find the data you're after. \n This is pretty easy to keep straight, once you see it. It looks like: \n \n \n \n \n \n session add uie ... session lookup uie \n \n Or: \n \n session add ssl ... session lookup ssl \n \n \n \n \n \n You can find complete documentation on the session command here, in the iRules, as well as some great examples that depict some more advanced iRules making use of the session command to great success. Check out Codeshare for more examples. ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"5067","kudosSumWeight":0,"repliesCount":8,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:289041":{"__typename":"Conversation","id":"conversation:289041","topic":{"__typename":"TkbTopicMessage","uid":289041},"lastPostingActivityTime":"2024-10-03T06:48:40.755-07:00","solved":false},"User:user:305638":{"__typename":"User","uid":305638,"login":"Valentin_Tobi","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0zMDU2MzgtMjE5NThpMzEwNzRGNTRCM0ZCREU4Rg"},"id":"user:305638"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODkwNDEtMTI3NzJpRUJGMTE0NkQyMkI1MEQzRQ?revision=1\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODkwNDEtMTI3NzJpRUJGMTE0NkQyMkI1MEQzRQ?revision=1","title":"0EM1T000001UHU0.png","associationType":"BODY","width":2526,"height":1130,"altText":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODkwNDEtMTU2MzBpRDU5NDgwNzk0NTMyQ0ZCRg?revision=1\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODkwNDEtMTU2MzBpRDU5NDgwNzk0NTMyQ0ZCRg?revision=1","title":"0EM1T000001UHU1.png","associationType":"BODY","width":2692,"height":832,"altText":null},"TkbTopicMessage:message:289041":{"__typename":"TkbTopicMessage","subject":"Declarative Advanced WAF policy lifecycle in a CI/CD pipeline","conversation":{"__ref":"Conversation:conversation:289041"},"id":"message:289041","revisionNum":1,"uid":289041,"depth":0,"board":{"__ref":"Tkb:board:TechnicalArticles"},"author":{"__ref":"User:user:305638"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":2246},"postTime":"2020-09-22T16:36:51.000-07:00","lastPublishTime":"2020-09-22T16:36:51.000-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" The purpose of this article is to show the configuration used to deploy a declarative Advanced WAF policy to a BIG-IP and automatically configure it to protect an API workload by consuming an OpenAPI file describing the application. For this experiment, a Gitlab CI/CD pipeline was used to deploy an API workload to Kubernetes, configure a declarative Adv. WAF policy to a BIG-IP device and tuning it by incorporating learning suggestions exported from the BIG-IP. Lastly, the F5 WAF tester tool was used to determine and improve the defensive posture of the Adv. WAF policy. Deploying the declarative Advanced WAF policy through a CI/CD pipeline To deploy the Adv. WAF policy, the Gitlab CI/CD pipeline is calling an Ansible playbook that will in turn deploy an AS3 application referencing the Adv.WAF policy from a separate JSON file. This allows the application definition and WAF policy to be managed by 2 different groups, for example NetOps and SecOps, supporting separation of duties. The following Ansible playbook was used; ---\n - hosts: bigip\n connection: local\n gather_facts: false\n vars:\n my_admin: \"xxxx\"\n my_password: \"xxxx\"\n bigip: \"xxxx\"\n\n tasks:\n - name: Deploy AS3 API AWAF policy\n uri:\n url: \"https://{{ bigip }}/mgmt/shared/appsvcs/declare\"\n method: POST\n headers:\n \"Content-Type\": \"application/json\"\n \"Authorization\": \"Basic xxxxxxxxxx\n body: \"{{ lookup('file','as3_waf_openapi.json') }}\"\n body_format: json\n validate_certs: no\n status_code: 200\n The Advanced WAF policy 'as3_waf_openapi.json' was specified as follows: {\n \"class\": \"AS3\",\n \"action\": \"deploy\",\n \"persist\": true,\n \"declaration\": {\n \"class\": \"ADC\",\n \"schemaVersion\": \"3.2.0\",\n \"id\": \"Prod_API_AS3\",\n \"API-Prod\": {\n \"class\": \"Tenant\",\n \"defaultRouteDomain\": 0,\n \"arcadia\": {\n \"class\": \"Application\",\n \"template\": \"generic\",\n \"VS_API\": {\n \"class\": \"Service_HTTPS\",\n \"remark\": \"Accepts HTTPS/TLS connections on port 443\",\n \"virtualAddresses\": [\"xxxxx\"],\n \"redirect80\": false,\n \"pool\": \"pool_NGINX_API\",\n \"policyWAF\": {\n \"use\": \"Arcadia_WAF_API_policy\"\n },\n \"securityLogProfiles\": [{\n \"bigip\": \"/Common/Log all requests\"\n }],\n \"profileTCP\": {\n \"egress\": \"wan\",\n \"ingress\": { \"use\": \"TCP_Profile\" } },\n \"profileHTTP\": { \"use\": \"custom_http_profile\" },\n \"serverTLS\": { \"bigip\": \"/Common/arcadia_client_ssl\" }\n },\n \"Arcadia_WAF_API_policy\": {\n \"class\": \"WAF_Policy\",\n \"url\": \"http://xxxx/root/awaf_openapi/-/raw/master/WAF/ansible/bigip/policy-api.json\",\n \"ignoreChanges\": true\n },\n \"pool_NGINX_API\": {\n \"class\": \"Pool\",\n \"monitors\": [\"http\"],\n \"members\": [{\n \"servicePort\": 8080,\n \"serverAddresses\": [\"xxxx\"]\n }]\n },\n \"custom_http_profile\": {\n \"class\": \"HTTP_Profile\",\n \"xForwardedFor\": true\n },\n \"TCP_Profile\": {\n \"class\": \"TCP_Profile\",\n \"idleTimeout\": 60 }\n }\n }\n }\n}\n The AS3 declaration will provision a separate Administrative Partition ('API-Prod') containing a Virtual Server ('VS_API'), an Adv. WAF policy ('Arcadia_WAF_API_policy') and a pool ('pool_NGINX_API'). The Adv.WAF policy being referenced ('policy-api.json') is stored in the same Gitlab repository but can be downloaded from a separate location. {\n \"policy\": {\n \"name\": \"policy-api-arcadia\",\n \"description\": \"Arcadia API\",\n \"template\": {\n \"name\": \"POLICY_TEMPLATE_API_SECURITY\"\n },\n \"enforcementMode\": \"transparent\",\n \"server-technologies\": [\n {\n \"serverTechnologyName\": \"MySQL\"\n },\n {\n \"serverTechnologyName\": \"Unix/Linux\"\n },\n {\n \"serverTechnologyName\": \"MongoDB\"\n }\n ],\n \"signature-settings\": {\n \"signatureStaging\": false\n },\n \"policy-builder\": {\n \"learnOnlyFromNonBotTraffic\": false\n },\n \"open-api-files\": [\n {\n \"link\": \"http://xxxx/root/awaf_openapi/-/raw/master/App/openapi3-arcadia.yaml\"\n }\n ]\n },\n \"modifications\": [\n ] \n}\n The declarative Adv.WAF policy is referencing in turn the OpenAPI file ('openapi3-arcadia.yaml') that describes the application being protected. Executing the Ansible playbook results in the AS3 application being deployed, along with the Adv.WAF policy that is automatically configured according to the OpenAPI file. Handling learning suggestions in a CI/CD pipeline The next step in the CI/CD pipeline used for this experiment was to send legitimate traffic using the API and collect the learning suggestions generated by the Adv.WAF policy, which will allow a simple way to customize the WAF policy further for the specific application being protected. The following Ansible playbook was used to retrieve the learning suggestions: ---\n - hosts: bigip\n connection: local\n gather_facts: true\n vars:\n my_admin: \"xxxx\"\n my_password: \"xxxx\"\n bigip: \"xxxxx\"\n\n tasks:\n - name: Get all Policy_key/IDs for WAF policies\n uri:\n url: 'https://{{ bigip }}/mgmt/tm/asm/policies?$select=name,id' \n method: GET\n headers:\n \"Authorization\": \"Basic xxxxxxxxxxx\"\n validate_certs: no\n status_code: 200\n return_content: yes\n register: waf_policies\n\n - name: Extract Policy_key/ID of Arcadia_WAF_API_policy\n set_fact: Arcadia_WAF_API_policy_ID=\"{{ item.id }}\"\n loop: \"{{ (waf_policies.content|from_json)['items'] }}\"\n when: item.name == \"Arcadia_WAF_API_policy\"\n\n - name: Export learning suggestions\n uri:\n url: \"https://{{ bigip }}/mgmt/tm/asm/tasks/export-suggestions\"\n method: POST\n headers:\n \"Content-Type\": \"application/json\"\n \"Authorization\": \"Basic xxxxxxxxxxx\"\n body: \"{ \\\"inline\\\": \\\"true\\\", \\\"policyReference\\\": { \\\"link\\\": \\\"https://{{ bigip }}/mgmt/tm/asm/policies/{{ Arcadia_WAF_API_policy_ID }}/\\\" } }\"\n body_format: json\n validate_certs: no\n status_code: \n - 200\n - 201\n - 202\n\n - name: Get learning suggestions\n uri:\n url: \"https://{{ bigip }}/mgmt/tm/asm/tasks/export-suggestions\"\n method: GET\n headers:\n \"Authorization\": \"Basic xxxxxxxxx\"\n validate_certs: no\n status_code: 200 \n register: result\n\n - name: Print learning suggestions\n debug: var=result\n A sample learning suggestions output is shown below: \"json\": {\n \"items\": [\n {\n \"endTime\": \"xxxxxxxxxxxxx\", \n \"id\": \"ZQDaRVecGeqHwAW1LDzZTQ\", \n \"inline\": true, \n \"kind\": \"tm:asm:tasks:export-suggestions:export-suggestions-taskstate\", \n \"lastUpdateMicros\": 1599953296000000.0, \n \"result\": {\n \"suggestions\": [\n {\n \"action\": \"add-or-update\", \n \"description\": \"Enable Evasion Technique\", \n \"entity\": {\n \"description\": \"Directory traversals\"\n }, \n \"entityChanges\": {\n \"enabled\": true\n }, \n \"entityType\": \"evasion\"\n }, \n {\n \"action\": \"add-or-update\", \n \"description\": \"Enable HTTP Check\", \n \"entity\": {\n \"description\": \"Check maximum number of parameters\"\n }, \n \"entityChanges\": {\n \"enabled\": true\n }, \n \"entityType\": \"http-protocol\"\n }, \n {\n \"action\": \"add-or-update\", \n \"description\": \"Enable HTTP Check\", \n \"entity\": {\n \"description\": \"No Host header in HTTP/1.1 request\"\n }, \n \"entityChanges\": {\n \"enabled\": true\n }, \n \"entityType\": \"http-protocol\"\n }, \n {\n \"action\": \"add-or-update\", \n \"description\": \"Enable enforcement of policy violation\", \n \"entity\": {\n \"name\": \"VIOL_REQUEST_MAX_LENGTH\"\n }, \n \"entityChanges\": {\n \"alarm\": true, \n \"block\": true\n }, \n \"entityType\": \"violation\"\n }\n Incorporating the learning suggestions in the Adv.WAF policy can be done by simple copy&pasting the self-contained learning suggestions blocks into the \"modifications\" list of the Adv.WAF policy: {\n \"policy\": {\n \"name\": \"policy-api-arcadia\",\n \"description\": \"Arcadia API\",\n \"template\": {\n \"name\": \"POLICY_TEMPLATE_API_SECURITY\"\n },\n \"enforcementMode\": \"transparent\",\n \"server-technologies\": [\n {\n \"serverTechnologyName\": \"MySQL\"\n },\n {\n \"serverTechnologyName\": \"Unix/Linux\"\n },\n {\n \"serverTechnologyName\": \"MongoDB\"\n }\n ],\n \"signature-settings\": {\n \"signatureStaging\": false\n },\n \"policy-builder\": {\n \"learnOnlyFromNonBotTraffic\": false\n },\n \"open-api-files\": [\n {\n \"link\": \"http://xxxxxx/root/awaf_openapi/-/raw/master/App/openapi3-arcadia.yaml\"\n }\n ]\n },\n \"modifications\": [\n {\n \"action\": \"add-or-update\", \n \"description\": \"Enable Evasion Technique\", \n \"entity\": {\n \"description\": \"Directory traversals\"\n }, \n \"entityChanges\": {\n \"enabled\": true\n }, \n \"entityType\": \"evasion\"\n }\n ] \n}\n Enhancing Advanced WAF policy posture by using the F5 WAF tester The F5 WAF tester is a tool that generates known attacks and checks the response of the WAF policy. For example, running the F5 WAF tester against a policy that has a \"transparent\" enforcement mode will cause the tests to fail as the attacks will not be blocked. The F5 WAF tester can suggest possible enhancement of the policy, in this case the change of the enforcement mode. An abbreviated sample output of the F5 WAF Tester: ................................................................\n \"100000023\": {\n \"CVE\": \"\", \n \"attack_type\": \"Server Side Request Forgery\", \n \"name\": \"SSRF attempt (AWS Metadata Server)\", \n \"results\": {\n \"parameter\": {\n \"expected_result\": {\n \"type\": \"signature\", \n \"value\": \"200018040\"\n }, \n \"pass\": false, \n \"reason\": \"ASM Policy is not in blocking mode\", \n \"support_id\": \"\"\n }\n }, \n \"system\": \"All systems\"\n }, \n \"100000024\": {\n \"CVE\": \"\", \n \"attack_type\": \"Server Side Request Forgery\", \n \"name\": \"SSRF attempt - Local network IP range 10.x.x.x\", \n \"results\": {\n \"request\": {\n \"expected_result\": {\n \"type\": \"signature\", \n \"value\": \"200020201\"\n }, \n \"pass\": false, \n \"reason\": \"ASM Policy is not in blocking mode\", \n \"support_id\": \"\"\n }\n }, \n \"system\": \"All systems\"\n }\n }, \n \"summary\": {\n \"fail\": 48, \n \"pass\": 0\n } \n Changing the enforcement mode from \"transparent\" to \"blocking\" can easily be done by editing the same Adv. WAF policy file: {\n \"policy\": {\n \"name\": \"policy-api-arcadia\",\n \"description\": \"Arcadia API\",\n \"template\": {\n \"name\": \"POLICY_TEMPLATE_API_SECURITY\"\n },\n \"enforcementMode\": \"blocking\",\n \"server-technologies\": [\n {\n \"serverTechnologyName\": \"MySQL\"\n },\n {\n \"serverTechnologyName\": \"Unix/Linux\"\n },\n {\n \"serverTechnologyName\": \"MongoDB\"\n }\n ],\n \"signature-settings\": {\n \"signatureStaging\": false\n },\n \"policy-builder\": {\n \"learnOnlyFromNonBotTraffic\": false\n },\n \"open-api-files\": [\n {\n \"link\": \"http://xxxxx/root/awaf_openapi/-/raw/master/App/openapi3-arcadia.yaml\"\n }\n ]\n },\n \"modifications\": [\n {\n \"action\": \"add-or-update\", \n \"description\": \"Enable Evasion Technique\", \n \"entity\": {\n \"description\": \"Directory traversals\"\n }, \n \"entityChanges\": {\n \"enabled\": true\n }, \n \"entityType\": \"evasion\"\n }\n ] \n}\n A successful run will will be achieved when all the attacks will be blocked. .........................................\n \"100000023\": {\n \"CVE\": \"\", \n \"attack_type\": \"Server Side Request Forgery\", \n \"name\": \"SSRF attempt (AWS Metadata Server)\", \n \"results\": {\n \"parameter\": {\n \"expected_result\": {\n \"type\": \"signature\", \n \"value\": \"200018040\"\n }, \n \"pass\": true, \n \"reason\": \"\", \n \"support_id\": \"17540898289451273964\"\n }\n }, \n \"system\": \"All systems\"\n }, \n \"100000024\": {\n \"CVE\": \"\", \n \"attack_type\": \"Server Side Request Forgery\", \n \"name\": \"SSRF attempt - Local network IP range 10.x.x.x\", \n \"results\": {\n \"request\": {\n \"expected_result\": {\n \"type\": \"signature\", \n \"value\": \"200020201\"\n }, \n \"pass\": true, \n \"reason\": \"\", \n \"support_id\": \"17540898289451274344\"\n }\n }, \n \"system\": \"All systems\"\n }\n }, \n \"summary\": {\n \"fail\": 0, \n \"pass\": 48\n }\n Conclusion By adding the Advanced WAF policy into a CI/CD pipeline, the WAF policy can be integrated in the lifecycle of the application it is protecting, allowing for continuous testing and improvement of the security posture before it is deployed to production. The flexible model of AS3 and declarative Advanced WAF allows the separation of roles and responsibilities between NetOps and SecOps, while providing an easy way for tuning the policy to the specifics of the application being protected. Links UDF lab environment link. Short instructional video link. ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"37779","kudosSumWeight":3,"repliesCount":2,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wx","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODkwNDEtMTI3NzJpRUJGMTE0NkQyMkI1MEQzRQ?revision=1\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wy","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODkwNDEtMTU2MzBpRDU5NDgwNzk0NTMyQ0ZCRg?revision=1\"}"}}],"totalCount":2,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:334776":{"__typename":"Conversation","id":"conversation:334776","topic":{"__typename":"TkbTopicMessage","uid":334776},"lastPostingActivityTime":"2024-10-03T05:00:00.041-07:00","solved":false},"User:user:242856":{"__typename":"User","uid":242856,"login":"MichaelOLeary","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0yNDI4NTYtMjA2NzVpMjAwQzU1OUQzMEFFMDM2RQ"},"id":"user:242856"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzQ3NzYtWm5yN2M4?revision=6\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzQ3NzYtWm5yN2M4?revision=6","title":"3-types-services.png","associationType":"BODY","width":936,"height":390,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzQ3NzYtRjJYS001?revision=6\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzQ3NzYtRjJYS001?revision=6","title":"clipboard_image-2-1727380740795.png","associationType":"BODY","width":400,"height":400,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzQ3NzYtUmVBaWRO?revision=6\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzQ3NzYtUmVBaWRO?revision=6","title":"clipboard_image-3-1727380740795.png","associationType":"BODY","width":847,"height":1025,"altText":""},"TkbTopicMessage:message:334776":{"__typename":"TkbTopicMessage","subject":"How to run an FTP server on Kubernetes with F5 BIG-IP","conversation":{"__ref":"Conversation:conversation:334776"},"id":"message:334776","revisionNum":6,"uid":334776,"depth":0,"board":{"__ref":"Tkb:board:TechnicalArticles"},"author":{"__ref":"User:user:242856"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" This article explains how you can run an FTP server in Kubernetes and expose securely with F5 BIG-IP. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":374},"postTime":"2024-10-03T05:00:00.041-07:00","lastPublishTime":"2024-10-03T05:00:00.041-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" This article explains how you can run an FTP server in Kubernetes and expose it securely with F5 BIG-IP. \n Background \n After 5 years of honing Kubernetes expertise, I was happy to undertake a challenge: expose an FTP server from within Kubernetes, and protecting with F5 BIG-IP. I’ll do this using Azure Kubernetes Service (AKS) as an example environment. \n Isn’t FTP a legacy technology? Yes, FTP has been around since the early 70’s. It was designed for efficient transfer of files. Although it’s insecure by default, it’s still commonly seen today for some file transfer types. \n \n Advantages of FTP \n As opposed to other file transfer methods, FTP does offer a few advantages: \n \n Allows applications to resume file transfers if a connection is lost \n Allows for a queue of files to be uploaded or downloaded \n Faster / more efficient than HTTP \n No file size limitations \n Extremely common platform offered widely for many years \n \n \n Disadvantages of FTP \n FTP is considered legacy because of a few limitations. There’s workarounds and enhancements, so I’ll give a basic overview: \n \n Insecure by default\n \n Standard FTP sends username, password, and files in clear text \n Servers can be spoofed to send data to the wrong client \n \n \n Complexity\n \n By default, the control channel is over TCP/21, but is usually configurable \n By default, the data channel is over a random high port, if using Passive mode, and is usually configurable \n By default, the data channel is over TCP/20, if using Active mode, and is usually configurable \n \n \n Active vs passive\n \n Active mode requires the server to establish a connection to a client. This is an outdated model disallowed by most firewalls \n Passive mode requires outbound connections over random high ports, which are also disallowed by most firewalls. Therefore, firewalls or L4 network devices (like BIG-IP) must be “ftp aware” \n \n \n \n There are many more complex advantages and disadvantages, but to summarize: running and securing FTP servers requires knowledge of the protocols, not just general network and security knowledge. \n \n FTPS and SFTP \n FTP is common, but it’s also common to see enterprises also offering FTPS and SFTP. While they sound similar, these two are different protocols. FTPS allows for encryption of the control channel and (optionally) the data channel of FTP. SFTP adds file transfers upon the SSH protocol, meaning all transfers can happen over a single TCP connection on port 22. \n There is some difficulty with all of these technologies. SFTP is difficult to proxy. FTPS requires additional knowledge on top of FTP, which itself is a learning curve for most folks. \n \n Common FTP servers \n For this reason, enterprise-level FTP servers are usually well-built out with a customer support team, static IP addresses, commercial software, and support. Changes are usually slow and upgrades infrequent. File transfers themselves are usually frequent, large, and core to a business process. For example, large financial customers may have longstanding practices built around FTP with partners, and so require very high confidence in the redundancy, security, and support of their FTP systems. \n In my most recent case, my customer was running IBM Sterling B2B Integrator installed Red Hat OpenShift. OpenShift is running on Azure (ARO). This means we had a commercial application running on an enterprise K8s distribution, which itself was running as a managed service in Azure. In my demonstration, I’m going to use a free FTP server, vsftp, and I will start by running on Azure Kubernetes Service (AKS). \n \n Why run FTP on Kubernetes? \n Kubernetes offers the same advantages for FTP applications as it does to others: scale, platform-agnostic, heavily automated deployment and operations, etc. But Kubernetes networking is a challenge for the average network engineer, and FTP applications are an additional challenge for the average engineer. FTP and K8s are not a likely combination, but it can be done! \n \n How to run your FTP server on Kubernetes and still get enterprise-level protection \n Service type of ClusterIP, NodePort, or LoadBalancer? \n Broadly speaking, there’s three major types of services in Kubernetes: ClusterIP, NodePort, and LoadBalancer. Whichever type you choose to expose your FTP service, you’re going to have some things to consider. \n source.\n ClusterIP \n Cluster IP is possible if your pods are directly routable by your external load balancer. With my AKS deployments, my pods are routable from the VNet without additional work. \n If you’re using a CNI with an overlay network (which typically use tunnels like VXLAN or GENEVE or routing like BGP), then you’ll need to get your external loadbalancer integrated with the CNI, or use another method. I won’t go into the details of CNI integration here. \n \n NodePort \n NodePort builds on ClusterIP, and maps a high port from the NodePort range (30000-32767) to the port exposed on the pod. \n However, with FTP, we cannot have random port translation. Since the data channel port is assigned by the server, it will tell the client to connect on an expected port. That port must be available to the client, and correctly mapped back to the server. \n With NodePort, we can manually define our NodePort values in our service, and match them with the PASV ports from your FTP server. Ie., like this: \n apiVersion: v1\nkind: Service\nmetadata:\n name: my-ftp-service\nspec:\n type: NodePort\n selector:\n app.kubernetes.io/name: MyApp\n ports: \n - port: 21\n targetPort: 21\n # no need for a pre-determined port for the control channel\n - port: 30100\n targetPort: 30100\n nodePort: 30100 # notice here, we have our PASV port range within the NodePort default range, and we match them manually.\n - port: 30101\n targetPort: 30101\n nodePort: 30101\n # etc... \n In reality, a NodePort service is a confusing option for exposing FTP services! \n \n LoadBalancer \n Creation of a LoadBalancer service builds upon NodePort. A controller will automatically configure a corresponding load balancer in the cloud. \n In this case, I’m running in Azure but I do not want to use an Azure Load Balancer, so I’ll create a service of type LoadBalancer but also define loadBalancerClass so the Azure controller ignores this resource. CIS will configure BIG-IP as the load balancer instead. \n \n \n \n Let’s deploy our cloud environment \n In this demo, I’ll use a LoadBalancer service and deploy my CIS instance in cluster mode. \n Build an Azure VNet with a few subnets. \n SUBSCRIPTION_ID=\"your-subscription-id\"\nLOCATION=eastus2\nRESOURCEGROUP=oleary-rg\nCLUSTER=mycluster\nVNET_NAME=my-vnet\n# create vnet\naz network vnet create --resource-group $RESOURCEGROUP --name $VNET_NAME --address-prefixes 10.0.0.0/16 --location $LOCATION\naz network vnet subnet create --resource-group $RESOURCEGROUP --vnet-name $VNET_NAME --name worker-subnet --address-prefixes 10.0.2.0/23\naz network vnet subnet create --resource-group $RESOURCEGROUP --vnet-name $VNET_NAME --name mgmt --address-prefixes 10.0.4.0/23\naz network vnet subnet create --resource-group $RESOURCEGROUP --vnet-name $VNET_NAME --name external --address-prefixes 10.0.6.0/23 \n \n Now, deploy a pair of F5 BIG-IP devices into the VNET, where the network interfaces are in the subnets of mgmt, external, and worker-subnet. \n Then, deploy an AKS cluster with the nodes in the worker-subnet subnet. \n # create AKS cluster\naz aks create --resource-group $RESOURCEGROUP --name $CLUSTER --node-count 1 --generate-ssh-keys --network-plugin azure --service-cidr \"172.16.0.0/24\" --dns-service-ip \"172.16.0.10\" --vnet-subnet-id /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/$VNET_NAME/subnets/worker-subnet\n# get kubeconfig file of AKS cluster\naz aks get-credentials -n $CLUSTER -g $RESOURCEGROUP -f ~/.kube/config \n \n Now, configure CIS in the cluster so that applications can be exposed from Kubernetes via BIG-IP. I won’t detail installing CIS here, except to say that I defined pool-member-type as cluster and load-balancer-class as f5cis, to match the spec in my service. \n I’m going to use Cluster mode (not NodePort mode) in this example, but either will work. \n At this point, you’ll have an environment that looks like this: \n \n \n \n Now, deploy your FTP server using YAML manifests like those I have attached to this article. \n \n First, a namespace. \n Second, a PersistentVolumeClaim. \n Then, a Deployment like this to run a FTP server. Notice that our deployment defines several environment variables within our pods, which are used to set the PASV FTP ports and the FTP server address. \n On the BIG-IP, create an iRule called /Common/ftp_ports that looks like this: when SERVER_CONNECTED { FTP::port 10000 10002 } \n Now, create an F5 Policy CRD. \n Finally, in order to have CIS create a VirtualServer on BIG-IP, a service of type LoadBalancer. \n \n \n Troubleshooting passive FTP \n Here are the points I keep in mind when troubleshooting FTP connections: \n \n I like to use tcpdump / Wireshark everywhere if FTP connections are failing. That means on the client, the BIG-IP, and the FTP server (if possible, because in K8s this may be harder). Look for where communication breaks down. \n Ideally, client sends username and password, then the PASV command. BIG-IP wants it's pool member (FTP server) to respond to PASV with it's own IP address and high port. BIG-IP will translate the IP address to it's VIP address (and it's own high port if the iRule above is used). \n The above point is the reason I have the deployment configured to use it's own Pod IP address as an env var. If I had a NodePort service, I would use the Node IP env var. See deployment YAML manifest. \n The BIG-IP Virtual Server requires an FTP profile, but only needs to expose port 21. The high ports are not additional VS's on BIG-IP. \n \n \n Testing our FTP application \n I’m going to use simple ftp commands at the linux command prompt. Below, I will connect to our FTP server with ftp -p 4.152.28.199, and then enter username and password when prompted. Then I will type ls in order to list the directory, which contains a single file test.txt. Finally, I will type bye to disconnect. \n ubuntu@ubuntu-Virtual-Machine:~$ ftp -p 4.152.28.199\nConnected to 4.152.28.199.\n220 (vsFTPd 3.0.2)\nName (4.152.28.199:ubuntu): vsftp\n331 Please specify the password.\nPassword:\n230 Login successful.\nRemote system type is UNIX.\nUsing binary mode to transfer files.\nftp> ls\n229 Entering Extended Passive Mode (|||32002|)\n150 Here comes the directory listing.\n-rw------- 1 ftp ftp 8 Aug 29 01:51 test.txt\n226 Directory send OK.\nftp> bye\n221 Goodbye. \n \n Here’s a very short clip using a graphical tool, WinSCP, to demonstrate the same thing: \n \n \n \n OpenShift vs other Kubernetes distributions \n You may notice in my example above that I have used fauria/vsftp as the container image for my FTP server. This will work in a regular K8s distro (I’ve used AKS in my PoC). OpenShift will require additional resources, such as a Security Context Constraint (SCC), so I have not documented this here. Perhaps in a future article. \n \n Conclusion \n It is possible to: \n \n Run FTP applications in Kubernetes \n Expose FTP services outside of the cluster \n Integrate external services, like F5 BIG-IP, with the FTP traffic \n Run this in public cloud or with enterprise services like Azure Red Hat OpenShift \n \n Most of this requires a skillset that covers legacy and modern technologies. If you undertake something like this, ensure you have a plan for high availability and commercial support. I'm happy to help - thanks for reading! ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"11972","kudosSumWeight":2,"repliesCount":0,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wx","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzQ3NzYtWm5yN2M4?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wy","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzQ3NzYtRjJYS001?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjQuMTF8Mi4xfG98MjV8X05WX3wz","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzQ3NzYtUmVBaWRO?revision=6\"}"}}],"totalCount":3,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"CachedAsset:text:en_US-components/customComponent/CustomComponent-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/customComponent/CustomComponent-1728320186000","value":{"errorMessage":"Error rendering component id: {customComponentId}","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/community/Navbar-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1728320186000","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","migrated-link-9":"Groups","migrated-link-7":"Technical Articles","migrated-link-8":"DevCentral News","migrated-link-1":"Technical Forum","migrated-link-10":"Community Groups","migrated-link-2":"Water Cooler","migrated-link-11":"F5 Groups","migrated-link-0":"Forums","article-series":"Article Series","migrated-link-5":"Community Articles","migrated-link-6":"Articles","security-insights":"Security Insights","migrated-link-3":"CrowdSRC","migrated-link-4":"CodeShare","migrated-link-12":"Events","migrated-link-13":"Suggestions"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1728320186000","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1728320186000","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1728320186000","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1728320186000","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1728320186000","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagSubscriptionAction-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagSubscriptionAction-1728320186000","value":{"success.follow.title":"Following Tag","success.unfollow.title":"Unfollowed Tag","success.follow.message.followAcrossCommunity":"You will be notified when this tag is used anywhere across the communtiy","success.unfollowtag.message":"You will no longer be notified when this tag is used anywhere in this place","success.unfollowtagAcrossCommunity.message":"You will no longer be notified when this tag is used anywhere across the community","unexpected.error.title":"Error - Action Failed","unexpected.error.message":"An unidentified problem occurred during the action you took. Please try again later.","buttonTitle":"{isSubscribed, select, true {Unfollow} false {Follow} other{}}","unfollow":"Unfollow"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageListTabs-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageListTabs-1728320186000","value":{"mostKudoed":"{value, select, IDEA {Most Votes} other {Most Likes}}","mostReplies":"Most Replies","mostViewed":"Most Viewed","newest":"{value, select, IDEA {Newest Ideas} OCCASION {Newest Events} other {Newest Topics}}","newestOccasions":"Newest Events","mostRecent":"Most Recent","noReplies":"No Replies Yet","noSolutions":"No Solutions Yet","solutions":"Solutions","mostRecentUserContent":"Most Recent","trending":"Trending","draft":"Drafts","spam":"Spam","abuse":"Abuse","moderation":"Moderation","tags":"Tags","PAST":"Past","UPCOMING":"Upcoming","sortBymostRecent":"Sort By Most Recent","sortBymostRecentUserContent":"Sort By Most Recent","sortBymostKudoed":"Sort By Most Likes","sortBymostReplies":"Sort By Most Replies","sortBymostViewed":"Sort By Most Viewed","sortBynewest":"Sort By Newest Topics","sortBynewestOccasions":"Sort By Newest Events","otherTabs":" Messages list in the {tab} for {conversationStyle}","guides":"Guides","archives":"Archives"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1728320186000","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1728320186000","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/OverflowNav-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/OverflowNav-1728320186000","value":{"toggleText":"More"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewInline-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewInline-1728320186000","value":{"bylineAuthor":"{bylineAuthor}","bylineBoard":"{bylineBoard}","anonymous":"Anonymous","place":"Place {bylineBoard}","gotoParent":"Go to parent {name}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMore-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Pager/PagerLoadMore-1728320186000","value":{"loadMore":"Show More"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1728320186000","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1728320186000","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1728320186000","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1728320186000","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageUnreadCount-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageUnreadCount-1728320186000","value":{"unread":"{count} unread","comments":"{count, plural, one { unread comment} other{ unread comments}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageViewCount-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageViewCount-1728320186000","value":{"textTitle":"{count, plural,one {View} other{Views}}","views":"{count, plural, one{View} other{Views}}"},"localOverride":false},"CachedAsset:text:en_US-components/kudos/KudosCount-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/kudos/KudosCount-1728320186000","value":{"textTitle":"{count, plural,one {{messageType, select, IDEA{Vote} other{Like}}} other{{messageType, select, IDEA{Votes} other{Likes}}}}","likes":"{count, plural, one{like} other{likes}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRepliesCount-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRepliesCount-1728320186000","value":{"textTitle":"{count, plural,one {{conversationStyle, select, IDEA{Comment} OCCASION{Comment} other{Reply}}} other{{conversationStyle, select, IDEA{Comments} OCCASION{Comments} other{Replies}}}}","comments":"{count, plural, one{Comment} other{Comments}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1728320186000","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1728320186000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1728320186000","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false}}}},"page":"/tags/TagPage/TagPage","query":{"nodeId":"category:Articles","tagName":"BIG-IP"},"buildId":"OKtI0OLKuXmERTJKBVqYX","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"f5","openTelemetryServiceVersion":"24.11.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/customComponent/CustomComponent/CustomComponent.tsx","./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/tags/TagsHeaderWidget/TagsHeaderWidget.tsx","./components/messages/MessageListForNodeByRecentActivityWidget/MessageListForNodeByRecentActivityWidget.tsx","./components/tags/TagSubscriptionAction/TagSubscriptionAction.tsx","../shared/client/components/common/List/ListGroup/ListGroup.tsx","./components/messages/MessageView/MessageView.tsx","./components/messages/MessageView/MessageViewInline/MessageViewInline.tsx","../shared/client/components/common/Pager/PagerLoadMore/PagerLoadMore.tsx"],"appGip":true,"scriptLoader":[]}