Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
duniter
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Monitor
Service Desk
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
nodes
typescript
duniter
Commits
3580852b
Commit
3580852b
authored
Dec 3, 2020
by
Éloïs
Browse files
Options
Downloads
Patches
Plain Diff
[fix] gva:anti-spam: handle reverse proxy case
parent
7cf78091
No related branches found
No related tags found
1 merge request
!1335
Gva proto 2
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
rust-libs/modules/duniter-gva/src/anti_spam.rs
+11
-11
11 additions, 11 deletions
rust-libs/modules/duniter-gva/src/anti_spam.rs
rust-libs/modules/duniter-gva/src/warp_.rs
+23
-8
23 additions, 8 deletions
rust-libs/modules/duniter-gva/src/warp_.rs
with
34 additions
and
19 deletions
rust-libs/modules/duniter-gva/src/anti_spam.rs
+
11
−
11
View file @
3580852b
...
@@ -82,9 +82,9 @@ impl AntiSpam {
...
@@ -82,9 +82,9 @@ impl AntiSpam {
true
true
}
}
}
}
pub
(
crate
)
async
fn
verify
(
&
self
,
remote_addr_opt
:
Option
<
std
::
net
::
Socket
Addr
>
)
->
bool
{
pub
(
crate
)
async
fn
verify
(
&
self
,
remote_addr_opt
:
Option
<
std
::
net
::
Ip
Addr
>
)
->
bool
{
if
let
Some
(
remote_addr
)
=
remote_addr_opt
{
if
let
Some
(
ip
)
=
remote_addr_opt
{
l
et
ip
=
remote_addr
.
ip
(
);
l
og
::
trace!
(
"GVA: receive request from {}"
,
ip
);
if
self
.whitelist
.contains
(
&
ip
)
{
if
self
.whitelist
.contains
(
&
ip
)
{
true
true
}
else
{
}
else
{
...
@@ -123,7 +123,7 @@ impl AntiSpam {
...
@@ -123,7 +123,7 @@ impl AntiSpam {
#[cfg(test)]
#[cfg(test)]
mod
tests
{
mod
tests
{
use
super
::
*
;
use
super
::
*
;
use
std
::
net
::{
Ipv4Addr
,
Ipv6Addr
,
SocketAddr
};
use
std
::
net
::{
Ipv4Addr
,
Ipv6Addr
};
use
tokio
::
time
::
delay_for
;
use
tokio
::
time
::
delay_for
;
const
LOCAL_IP4
:
IpAddr
=
IpAddr
::
V4
(
Ipv4Addr
::
LOCALHOST
);
const
LOCAL_IP4
:
IpAddr
=
IpAddr
::
V4
(
Ipv4Addr
::
LOCALHOST
);
...
@@ -135,33 +135,33 @@ mod tests {
...
@@ -135,33 +135,33 @@ mod tests {
assert!
(
!
anti_spam
.verify
(
None
)
.await
);
assert!
(
!
anti_spam
.verify
(
None
)
.await
);
for
_
in
0
..
(
COUNT_INTERVAL
*
2
)
{
for
_
in
0
..
(
COUNT_INTERVAL
*
2
)
{
assert!
(
anti_spam
.verify
(
Some
(
SocketAddr
::
new
(
LOCAL_IP4
,
0
)
))
.await
);
assert!
(
anti_spam
.verify
(
Some
(
LOCAL_IP4
))
.await
);
assert!
(
anti_spam
.verify
(
Some
(
SocketAddr
::
new
(
LOCAL_IP6
,
0
)
))
.await
);
assert!
(
anti_spam
.verify
(
Some
(
LOCAL_IP6
))
.await
);
}
}
let
extern_ip
=
IpAddr
::
V4
(
Ipv4Addr
::
UNSPECIFIED
);
let
extern_ip
=
IpAddr
::
V4
(
Ipv4Addr
::
UNSPECIFIED
);
// Consume max queries
// Consume max queries
for
_
in
0
..
COUNT_INTERVAL
{
for
_
in
0
..
COUNT_INTERVAL
{
assert!
(
anti_spam
.verify
(
Some
(
SocketAddr
::
new
(
extern_ip
,
0
)
))
.await
);
assert!
(
anti_spam
.verify
(
Some
(
extern_ip
))
.await
);
}
}
// Should be banned
// Should be banned
assert!
(
!
anti_spam
.verify
(
Some
(
SocketAddr
::
new
(
extern_ip
,
0
)
))
.await
);
assert!
(
!
anti_spam
.verify
(
Some
(
extern_ip
))
.await
);
// Should be un-banned after one second
// Should be un-banned after one second
delay_for
(
Duration
::
from_millis
(
1_100
))
.await
;
delay_for
(
Duration
::
from_millis
(
1_100
))
.await
;
// Re-consume max queries
// Re-consume max queries
for
_
in
0
..
COUNT_INTERVAL
{
for
_
in
0
..
COUNT_INTERVAL
{
assert!
(
anti_spam
.verify
(
Some
(
SocketAddr
::
new
(
extern_ip
,
0
)
))
.await
);
assert!
(
anti_spam
.verify
(
Some
(
extern_ip
))
.await
);
}
}
// Should be banned for 2 seconds this time
// Should be banned for 2 seconds this time
delay_for
(
Duration
::
from_millis
(
1_100
))
.await
;
delay_for
(
Duration
::
from_millis
(
1_100
))
.await
;
// Attempting a request when I'm banned must be twice my banning time
// Attempting a request when I'm banned must be twice my banning time
assert!
(
!
anti_spam
.verify
(
Some
(
SocketAddr
::
new
(
extern_ip
,
0
)
))
.await
);
assert!
(
!
anti_spam
.verify
(
Some
(
extern_ip
))
.await
);
delay_for
(
Duration
::
from_millis
(
4_100
))
.await
;
delay_for
(
Duration
::
from_millis
(
4_100
))
.await
;
// Re-consume max queries
// Re-consume max queries
for
_
in
0
..
COUNT_INTERVAL
{
for
_
in
0
..
COUNT_INTERVAL
{
assert!
(
anti_spam
.verify
(
Some
(
SocketAddr
::
new
(
extern_ip
,
0
)
))
.await
);
assert!
(
anti_spam
.verify
(
Some
(
extern_ip
))
.await
);
}
}
}
}
}
}
This diff is collapsed.
Click to expand it.
rust-libs/modules/duniter-gva/src/warp_.rs
+
23
−
8
View file @
3580852b
...
@@ -13,6 +13,8 @@
...
@@ -13,6 +13,8 @@
// You should have received a copy of the GNU Affero General Public License
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use
std
::
net
::{
IpAddr
,
SocketAddr
};
use
crate
::
anti_spam
::
AntiSpam
;
use
crate
::
anti_spam
::
AntiSpam
;
use
crate
::
*
;
use
crate
::
*
;
...
@@ -58,24 +60,29 @@ pub(crate) fn graphql(
...
@@ -58,24 +60,29 @@ pub(crate) fn graphql(
let
anti_spam
=
AntiSpam
::
from
(
conf
);
let
anti_spam
=
AntiSpam
::
from
(
conf
);
let
opts
=
Arc
::
new
(
opts
);
let
opts
=
Arc
::
new
(
opts
);
warp
::
path
::
path
(
conf
.get_path
())
warp
::
path
::
path
(
conf
.get_path
())
.and
(
warp
::
addr
::
remote
())
.and
(
warp
::
method
())
.and
(
warp
::
method
())
.and
(
warp
::
query
::
raw
()
.or
(
warp
::
any
()
.map
(
String
::
new
))
.unify
())
.and
(
warp
::
query
::
raw
()
.or
(
warp
::
any
()
.map
(
String
::
new
))
.unify
())
.and
(
warp
::
addr
::
remote
())
.and
(
warp
::
header
::
optional
::
<
IpAddr
>
(
"X-Real-IP"
))
.and
(
warp
::
header
::
optional
::
<
String
>
(
"content-type"
))
.and
(
warp
::
header
::
optional
::
<
String
>
(
"content-type"
))
.and
(
warp
::
body
::
stream
())
.and
(
warp
::
body
::
stream
())
.and
(
warp
::
any
()
.map
(
move
||
opts
.clone
()))
.and
(
warp
::
any
()
.map
(
move
||
opts
.clone
()))
.and
(
warp
::
any
()
.map
(
move
||
schema
.clone
()))
.and
(
warp
::
any
()
.map
(
move
||
schema
.clone
()))
.and
(
warp
::
any
()
.map
(
move
||
anti_spam
.clone
()))
.and
(
warp
::
any
()
.map
(
move
||
anti_spam
.clone
()))
.and_then
(
.and_then
(
|
remote_addr
,
|
method
,
method
,
query
:
String
,
query
:
String
,
remote_addr
:
Option
<
SocketAddr
>
,
x_real_ip
:
Option
<
IpAddr
>
,
content_type
,
content_type
,
body
,
body
,
opts
:
Arc
<
async_graphql
::
http
::
MultipartOptions
>
,
opts
:
Arc
<
async_graphql
::
http
::
MultipartOptions
>
,
schema
,
schema
,
anti_spam
:
AntiSpam
|
async
move
{
anti_spam
:
AntiSpam
|
async
move
{
if
anti_spam
.verify
(
remote_addr
)
.await
{
if
anti_spam
.verify
(
x_real_ip
.or_else
(||
remote_addr
.map
(|
ra
|
ra
.ip
())))
.await
{
if
method
==
http
::
Method
::
GET
{
if
method
==
http
::
Method
::
GET
{
let
request
:
async_graphql
::
Request
=
serde_urlencoded
::
from_str
(
&
query
)
let
request
:
async_graphql
::
Request
=
serde_urlencoded
::
from_str
(
&
query
)
.map_err
(|
err
|
warp
::
reject
::
custom
(
BadRequest
(
err
.into
())))
?
;
.map_err
(|
err
|
warp
::
reject
::
custom
(
BadRequest
(
err
.into
())))
?
;
...
@@ -96,7 +103,7 @@ pub(crate) fn graphql(
...
@@ -96,7 +103,7 @@ pub(crate) fn graphql(
}
}
}
else
{
}
else
{
Err
(
warp
::
reject
::
custom
(
BadRequest
(
anyhow
::
Error
::
msg
(
Err
(
warp
::
reject
::
custom
(
BadRequest
(
anyhow
::
Error
::
msg
(
"too many requests"
,
r#"{ "error":
"too many requests"
}"#
,
))))
))))
}
}
},
},
...
@@ -115,16 +122,24 @@ pub(crate) fn graphql_ws(
...
@@ -115,16 +122,24 @@ pub(crate) fn graphql_ws(
let
anti_spam
=
AntiSpam
::
from
(
conf
);
let
anti_spam
=
AntiSpam
::
from
(
conf
);
warp
::
path
::
path
(
conf
.get_subscriptions_path
())
warp
::
path
::
path
(
conf
.get_subscriptions_path
())
.and
(
warp
::
addr
::
remote
())
.and
(
warp
::
addr
::
remote
())
.and
(
warp
::
header
::
optional
::
<
IpAddr
>
(
"X-Real-IP"
))
.and
(
warp
::
ws
())
.and
(
warp
::
ws
())
.and
(
warp
::
any
()
.map
(
move
||
schema
.clone
()))
.and
(
warp
::
any
()
.map
(
move
||
schema
.clone
()))
.and
(
warp
::
any
()
.map
(
move
||
anti_spam
.clone
()))
.and
(
warp
::
any
()
.map
(
move
||
anti_spam
.clone
()))
.and_then
(
.and_then
(
|
remote_addr
,
ws
:
warp
::
ws
::
Ws
,
schema
:
GraphQlSchema
,
anti_spam
:
AntiSpam
|
async
move
{
|
remote_addr
:
Option
<
SocketAddr
>
,
if
anti_spam
.verify
(
remote_addr
)
.await
{
x_real_ip
:
Option
<
IpAddr
>
,
ws
:
warp
::
ws
::
Ws
,
schema
:
GraphQlSchema
,
anti_spam
:
AntiSpam
|
async
move
{
if
anti_spam
.verify
(
x_real_ip
.or_else
(||
remote_addr
.map
(|
ra
|
ra
.ip
())))
.await
{
Ok
((
ws
,
schema
))
Ok
((
ws
,
schema
))
}
else
{
}
else
{
Err
(
warp
::
reject
::
custom
(
BadRequest
(
anyhow
::
Error
::
msg
(
Err
(
warp
::
reject
::
custom
(
BadRequest
(
anyhow
::
Error
::
msg
(
"too many requests"
,
r#"{ "error":
"too many requests"
}"#
,
))))
))))
}
}
},
},
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
sign in
to comment