@@ -28,6 +28,7 @@ import (
2828 "fmt"
2929 "net/http"
3030 "net/netip"
31+ "os/exec"
3132 "sort"
3233 "strings"
3334 "testing"
@@ -1155,6 +1156,141 @@ spec:
11551156 })
11561157}
11571158
1159+ func TestAuthorizationL4 (t * testing.T ) {
1160+ framework .NewTest (t ).Run (func (t framework.TestContext ) {
1161+ t .NewSubTest ("L4 Authorization" ).Run (func (t framework.TestContext ) {
1162+ // Enable authorizaiton offload to xdp.
1163+
1164+ if len (apps .ServiceWithWaypointAtServiceGranularity ) == 0 {
1165+ t .Fatal (fmt .Errorf ("need at least 1 instance of apps.ServiceWithWaypointAtServiceGranularity" ))
1166+ }
1167+ src := apps .ServiceWithWaypointAtServiceGranularity [0 ]
1168+
1169+ clients := src .WorkloadsOrFail (t )
1170+ dst := apps .EnrolledToKmesh
1171+
1172+ addresses := clients .Addresses ()
1173+ if len (addresses ) < 2 {
1174+ t .Fatal (fmt .Errorf ("need at least 2 clients" ))
1175+ }
1176+ selectedAddress := addresses [0 ]
1177+
1178+ authzCases := []struct {
1179+ name string
1180+ spec string
1181+ }{
1182+ {
1183+ name : "allow" ,
1184+ spec : `
1185+ action: ALLOW
1186+ ` ,
1187+ },
1188+ {
1189+ name : "deny" ,
1190+ spec : `
1191+ action: DENY
1192+ ` ,
1193+ },
1194+ }
1195+
1196+ chooseChecker := func (action string , ip string ) echo.Checker {
1197+ switch action {
1198+ case "allow" :
1199+ if ip != selectedAddress {
1200+ return check .NotOK ()
1201+ } else {
1202+ return check .OK ()
1203+ }
1204+ case "deny" :
1205+ if ip != selectedAddress {
1206+ return check .OK ()
1207+ } else {
1208+ return check .NotOK ()
1209+ }
1210+ default :
1211+ t .Fatal ("invalid action" )
1212+ }
1213+
1214+ return check .OK ()
1215+ }
1216+
1217+ count := 0
1218+ workloads := dst .WorkloadsOrFail (t )
1219+ for _ , client := range workloads {
1220+ if count == len (workloads ) {
1221+ break
1222+ }
1223+ podName := client .PodName ()
1224+ namespace := apps .Namespace .Name ()
1225+ timeout := time .After (5 * time .Second )
1226+ ticker := time .NewTicker (500 * time .Millisecond )
1227+ defer ticker .Stop ()
1228+ InnerLoop:
1229+ for {
1230+ select {
1231+ case <- timeout :
1232+ t .Fatalf ("Timeout: XDP eBPF program not found on pod %s" , podName )
1233+ case <- ticker .C :
1234+ cmd := exec .Command ("kubectl" , "exec" , "-n" , namespace , podName , "--" , "sh" , "-c" , "ip a | grep xdp" )
1235+ output , err := cmd .CombinedOutput ()
1236+ if err == nil && len (output ) > 0 {
1237+ t .Logf ("XDP program is loaded on pod %s" , podName )
1238+ count ++
1239+ break InnerLoop
1240+ }
1241+ t .Logf ("Waiting for XDP program to load on pod %s: %v" , podName , err )
1242+ }
1243+ }
1244+ }
1245+
1246+ for _ , tc := range authzCases {
1247+ t .ConfigIstio ().Eval (apps .Namespace .Name (), map [string ]string {
1248+ "Destination" : dst .Config ().Service ,
1249+ "Ip" : selectedAddress ,
1250+ }, `apiVersion: security.istio.io/v1beta1
1251+ kind: AuthorizationPolicy
1252+ metadata:
1253+ name: policy
1254+ spec:
1255+ selector:
1256+ matchLabels:
1257+ app: "{{.Destination}}"
1258+ ` + tc .spec + `
1259+ rules:
1260+ - from:
1261+ - source:
1262+ ipBlocks:
1263+ - "{{.Ip}}"
1264+ ` ).ApplyOrFail (t )
1265+
1266+ for _ , client := range clients {
1267+ opt := echo.CallOptions {
1268+ To : dst ,
1269+ Port : echo.Port {Name : "tcp" },
1270+ Scheme : scheme .TCP ,
1271+ NewConnectionPerRequest : true ,
1272+ // Due to the mechanism of Kmesh L4 authorization, we need to set the timeout slightly longer.
1273+ Timeout : time .Minute * 2 ,
1274+ }
1275+
1276+ var name string
1277+ if client .Address () != selectedAddress {
1278+ name = tc .name + ", not selected address"
1279+ } else {
1280+ name = tc .name + ", selected address"
1281+ }
1282+
1283+ opt .Check = chooseChecker (tc .name , client .Address ())
1284+
1285+ t .NewSubTestf ("%v" , name ).Run (func (t framework.TestContext ) {
1286+ src .WithWorkloads (client ).CallOrFail (t , opt )
1287+ })
1288+ }
1289+ }
1290+ })
1291+ })
1292+ }
1293+
11581294func getSupportedIPFamilies (t framework.TestContext ) (v4 bool , v6 bool ) {
11591295 addrs := apps .All .WorkloadsOrFail (t ).Addresses ()
11601296 for _ , a := range addrs {
0 commit comments