Skip to content

Conversation

@kawaiirice
Copy link

@kawaiirice kawaiirice commented Jun 29, 2016

Documentation for extending ip_allow.config to filter destination IP addresses, as proposed by Edge. @SolidWallOfCode @shinrich

@kawaiirice
Copy link
Author

kawaiirice commented Jul 1, 2016

dest_ip filtering has been implemented and tested for blocking connections at remap.
The test used was dest_ip=10.0.0.0-10.0.0.255 action=ip_deny method=ALL in ip_allow.config and map http://127.0.0.1:8080 http://10.0.0.10 in remap.config.

Also tested for normal functionality in default/normal configurations of traffic server.

@zwoop
Copy link
Contributor

zwoop commented Jul 23, 2016

[approve ci]

@atsci
Copy link

atsci commented Jul 23, 2016

Linux build failed! See https://ci.trafficserver.apache.org/job/Github-Linux/375/ for details.

@atsci
Copy link

atsci commented Jul 23, 2016

FreeBSD build successful! See https://ci.trafficserver.apache.org/job/Github-FreeBSD/478/ for details.

@zwoop
Copy link
Contributor

zwoop commented Aug 18, 2016

@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));
Copy link
Member

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));

@SolidWallOfCode
Copy link
Member

SolidWallOfCode commented Sep 12, 2016

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).

@zwoop zwoop modified the milestones: 7.1.0, 7.0.0 Sep 15, 2016
proxy/IPAllow.cc Outdated
const AclRecord IpAllow::ALL_METHOD_ACL(AclRecord::ALL_METHOD_MASK);

int IpAllow::configid = 0;
bool IpAllow::accept_check_p = true;
Copy link
Member

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) {
Copy link
Member

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) {
Copy link
Member

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.

Copy link
Member

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;
Copy link
Member

@SolidWallOfCode SolidWallOfCode Oct 7, 2016

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
Copy link
Member

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) {
Copy link
Member

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.


// 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)) {
Copy link
Member

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.

Copy link
Author

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?

// 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;
Copy link
Member

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.

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)),
Copy link
Member

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]"
Copy link
Member

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.

Copy link
Author

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

Copy link
Member

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".

}
errStr = remap_validate_filter_args(rpp, (const char **)bti->argv, bti->argc, errStrBuf, errStrBufSize);
}
// Copy ip_allow_flag to url_mapping
Copy link
Member

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"

}

// update sticky flag
bti->accept_check_p &= (bool)bti->ip_allow_flag;
Copy link
Member

@SolidWallOfCode SolidWallOfCode Oct 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&&= - logical and.

return false;
} /* end of while(cur_line != NULL) */

(void)IpAllow::enableAcceptCheck(bti->accept_check_p);
Copy link
Member

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)?

char *paramv[BUILD_TABLE_MAX_ARGS];
char *argv[BUILD_TABLE_MAX_ARGS];

unsigned int ip_allow_flag : 1;
Copy link
Member

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?

Copy link
Member

@SolidWallOfCode SolidWallOfCode left a 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.


// 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)) {
Copy link
Member

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]"
Copy link
Member

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".

}

// update sticky flag
bti->accept_check_p = bti->accept_check_p && (bool)bti->ip_allow_check_enabled_p;
Copy link
Member

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.

@SolidWallOfCode SolidWallOfCode merged commit b92a6b3 into apache:master Nov 2, 2016
@kawaiirice
Copy link
Author

Finally done!

JosiahWI pushed a commit to JosiahWI/trafficserver that referenced this pull request Jul 19, 2023
…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)
masaori335 pushed a commit to masaori335/trafficserver that referenced this pull request May 29, 2025
* Stricten field name check

* Add a test

---------

Co-authored-by: Masakazu Kitajo <maskit@apache.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants