-
Notifications
You must be signed in to change notification settings - Fork 848
TS 4593: Extend ip_allow.config to filter destination IPs #769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
dest_ip filtering has been implemented and tested for blocking connections at remap. Also tested for normal functionality in default/normal configurations of traffic server. |
|
[approve ci] |
|
Linux build failed! See https://ci.trafficserver.apache.org/job/Github-Linux/375/ for details. |
|
FreeBSD build successful! See https://ci.trafficserver.apache.org/job/Github-FreeBSD/478/ for details. |
|
@SolidWallOfCode Are we ready to land this? |
proxy/IPAllow.cc
Outdated
| // is volatile. | ||
| _map.fill(&addr1, &addr2, reinterpret_cast<void *>(_acls.length() - 1)); | ||
| if(is_dest_ip) { | ||
| _dest_acls.push_back(AclRecord(acl_method_mask, line_num, nonstandard_methods, deny_nonstandard_methods)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These cases should be more compact by selecting the map then applying the fill.
Vec<AclRecord>& acls = is_dest_ip ? _dest_acls : _src_acls;
IpMap& map = is_dest_ip ? _dest_map : _src_map;
acls.push_back(AclRecord(acl_method_mask, line_num, nonstandard_methods, deny_nonstandard_methods));
map.fill(&addr1, &addr2, reinterpret_cast<void *>(_dest_acls.length() - 1));
|
Where is the change that disables the fast accept check? That's needed or a deny can't be overridden by remap. Currently if in the IP allow configuration all methods are denied, the connection is dropped immediately after the ACCEPT event. That can't be done if remap configuration is to override such a deny (which is the essential feature requested for this fix). |
proxy/IPAllow.cc
Outdated
| const AclRecord IpAllow::ALL_METHOD_ACL(AclRecord::ALL_METHOD_MASK); | ||
|
|
||
| int IpAllow::configid = 0; | ||
| bool IpAllow::accept_check_p = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments, please.
proxy/IPAllow.cc
Outdated
| errPtr = parseConfigLine(line, &line_info, &ip_allow_tags); | ||
|
|
||
| if (errPtr != NULL) { | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clang format or tweak your editor to cleanup trailing space.
proxy/IPAllow.cc
Outdated
| // convert the coloring from indices to pointers. | ||
| for (IpMap::iterator spot(_map.begin()), limit(_map.end()); spot != limit; ++spot) { | ||
| spot->setData(&_acls[reinterpret_cast<size_t>(spot->data())]); | ||
| for (IpMap::iterator spot(_src_map.begin()), limit(_src_map.end()); spot != limit; ++spot) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's convert these to lambda's now that we have eleventy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, how about container style for loops?
for ( auto& item : _src_map )
item.setData(&_acls[reinterpret_cast<size_t>(item.data())]);
proxy/IPAllow.h
Outdated
| void Print(); | ||
| AclRecord *match(IpEndpoint const *ip) const; | ||
| AclRecord *match(sockaddr const *ip) const; | ||
| AclRecord *match(IpEndpoint const *ip, bool is_dest_ip) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's change this to an enum like
enum class match_key_t { SRC_ADDR, DST_ADDR };
This should make the call site clearer.
proxy/IPAllow.h
Outdated
| return &ALL_METHOD_ACL; | ||
| } | ||
|
|
||
| /// @return The previous accept check state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment that this is independent of the configuration and is therefore a class global so it can be changed without changing the configuration.
proxy/IPAllow.h
Outdated
| void *raw; | ||
| if (_map.contains(ip, &raw)) { | ||
| return static_cast<AclRecord *>(raw); | ||
| if(is_dest_ip) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
IpAllow::match(sockaddr const* ip, match_key_t key) {
void *raw = NULL;
this->map(key).contains(ip, &raw);
return static_cast<AclRecord*>(raw);
Then define
IpMap& map(match_key_t key) { return key == SRC_ADDR ? _src_map : _dest_map; }
This could be used elsewhere instead of the current ternary operator for cleaner code.
proxy/http/HttpSM.cc
Outdated
|
|
||
| // Check for remap rule. If so, only apply ip_allow filter if it is activated (ip_allow_flag set). | ||
| // Otherwise, if no remap rule is defined, apply the ip_allow filter. | ||
| if(!t_state.url_remap_success || (t_state.url_remap_success && t_state.url_map.getMapping()->ip_allow_flag)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For performance reasons we should probably have a short cut that prevents as much of this as possible if there are no destination address rules. That might be worth having a specific method in the configuration object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is checking acl_record->isEmpty() right after finding a match for the server ip considered too late?
proxy/http/HttpSM.cc
Outdated
| // Method allowed on dest IP address check | ||
| sockaddr *server_ip = &t_state.current.server->dst_addr.sa; | ||
| IpAllow::scoped_config ip_allow; | ||
| const AclRecord *acl_record = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move these inside the if - no need to compute them if there's no IP allow configuration.
proxy/http/HttpSM.cc
Outdated
| if (is_debug_tag_set("ip-allow")) { | ||
| ip_text_buffer ipb; | ||
| Warning("server '%s' prohibited by ip-allow policy", ats_ip_ntop(server_ip, ipb, sizeof(ipb))); | ||
| Debug("ip-allow", "Quick filter denial on %s:%s with mask %x", ats_ip_ntop(&t_state.current.server->dst_addr.sa, ipb, sizeof(ipb)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Quick filter"?
| void | ||
| HttpTransact::Forbidden(State *s) | ||
| { | ||
| DebugTxn("http_trans", "[Forbidden]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this here prior to the patch? "parser marked" seems incorrect, unless it's legacy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this Forbidden state and copied the debug message from the BadRequest state
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but the descriptive text should be updated to "IPAllow marked request forbidden".
proxy/http/remap/RemapConfig.cc
Outdated
| } | ||
| errStr = remap_validate_filter_args(rpp, (const char **)bti->argv, bti->argc, errStrBuf, errStrBufSize); | ||
| } | ||
| // Copy ip_allow_flag to url_mapping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Set the ip allow flag for this rule to the current ip allow flag state"
proxy/http/remap/RemapConfig.cc
Outdated
| } | ||
|
|
||
| // update sticky flag | ||
| bti->accept_check_p &= (bool)bti->ip_allow_flag; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
&&= - logical and.
proxy/http/remap/RemapConfig.cc
Outdated
| return false; | ||
| } /* end of while(cur_line != NULL) */ | ||
|
|
||
| (void)IpAllow::enableAcceptCheck(bti->accept_check_p); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did the compiler actually complain about this, to require the (void)?
proxy/http/remap/RemapConfig.h
Outdated
| char *paramv[BUILD_TABLE_MAX_ARGS]; | ||
| char *argv[BUILD_TABLE_MAX_ARGS]; | ||
|
|
||
| unsigned int ip_allow_flag : 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, need a better name. "ip_allow_check_enabled_p" maybe?
…led from remap. (#1) Merged
SolidWallOfCode
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worked with @kawaiirice to get this fixed up.
proxy/http/HttpSM.cc
Outdated
|
|
||
| // Check for remap rule. If so, only apply ip_allow filter if it is activated (ip_allow_check_enabled_p set). | ||
| // Otherwise, if no remap rule is defined, apply the ip_allow filter. | ||
| if(!t_state.url_remap_success || (t_state.url_remap_success && t_state.url_map.getMapping()->ip_allow_check_enabled_p)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be simplified to
if(!t_state.url_remap_success || t_state.url_map.getMapping()->ip_allow_check_enabled_p))
The second clause can only be checked if t_state.url_remap_success is true - otherwise the first clause would have been true and the evaluation stopped, so there's no need to check it again.
| void | ||
| HttpTransact::Forbidden(State *s) | ||
| { | ||
| DebugTxn("http_trans", "[Forbidden]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but the descriptive text should be updated to "IPAllow marked request forbidden".
proxy/http/remap/RemapConfig.cc
Outdated
| } | ||
|
|
||
| // update sticky flag | ||
| bti->accept_check_p = bti->accept_check_p && (bool)bti->ip_allow_check_enabled_p; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about bti->accept_check_p &&= bit->ip_allow_check_enabled_p; ? Is the cast to bool required? I would think ip_allow_check_enabled_p to be declared as bool. Also, I'm not sure this is the correct place to update the sticky flag. Activating other filters should have no effect on the sticky flag, only defining rules. I'l look at at putting it back around line 128, after the update to the rule flag.
|
Finally done! |
…e#769) A number of tests were flakey because of race conditions between the AuTest framework finishing the Default TestRun process and ending the test, and therefore the traffic server process, before traffic server had time to exercise the expected functionality of the test. This improves the Ready conditions for these tests which should improve their reliability. (cherry picked from commit c175aa4)
* Stricten field name check * Add a test --------- Co-authored-by: Masakazu Kitajo <maskit@apache.org>
Documentation for extending ip_allow.config to filter destination IP addresses, as proposed by Edge. @SolidWallOfCode @shinrich