Bypass ILV kuzuia na DNStap na BGP

Bypass ILV kuzuia na DNStap na BGP

Mada imepigwa sana, najua. Kwa mfano, kuna kubwa makala, lakini sehemu ya IP tu ya orodha ya kuzuia inazingatiwa hapo. Pia tutaongeza vikoa.

Kutokana na ukweli kwamba mahakama na RKN huzuia kila kitu kulia na kushoto, na watoa huduma wanajaribu sana si kuanguka chini ya faini iliyotolewa na Revizorro, hasara zinazohusiana na kuzuia ni kubwa kabisa. Na kati ya tovuti "zilizozuiwa" kuna nyingi muhimu (hello, rutracker)

Ninaishi nje ya mamlaka ya RKN, lakini wazazi wangu, jamaa na marafiki walibaki nyumbani. Kwa hivyo iliamuliwa kuja na njia rahisi kwa watu walio mbali na IT kukwepa kuzuia, ikiwezekana bila ushiriki wao hata kidogo.

Katika maelezo haya, sitaelezea mambo ya msingi ya mtandao kwa hatua, lakini nitaelezea kanuni za jumla za jinsi mpango huu unaweza kutekelezwa. Kwa hivyo ujuzi wa jinsi mtandao unavyofanya kazi kwa ujumla na katika Linux haswa ni lazima uwe nayo.

Aina za kufuli

Kwanza, hebu turudishe kumbukumbu yetu ya kile kinachozuiwa.

Kuna aina kadhaa za kufuli kwenye XML iliyopakuliwa kutoka kwa RKN:

  • IP
  • Jina la Jina
  • URL

Kwa unyenyekevu, tutazipunguza hadi mbili: IP na kikoa, na tutaondoa kikoa kutoka kwa kuzuia kwa URL (kwa usahihi zaidi, tayari wametufanyia hili).

watu wazuri kutoka Roskomsvoboda kutambua ajabu API, ambayo kupitia kwayo tunaweza kupata kile tunachohitaji:

Ufikiaji wa tovuti zilizozuiwa

Ili kufanya hivyo, tunahitaji VPS ndogo za kigeni, ikiwezekana na trafiki isiyo na kikomo - kuna mengi ya haya kwa pesa 3-5. Unahitaji kuichukua karibu na nje ya nchi ili ping si kubwa sana, lakini tena, kuzingatia kwamba mtandao na jiografia si mara zote sanjari. Na kwa kuwa hakuna SLA kwa pesa 5, ni bora kuchukua vipande 2+ kutoka kwa watoa huduma tofauti kwa uvumilivu wa makosa.

Ifuatayo, tunahitaji kusanidi handaki iliyosimbwa kutoka kwa kipanga njia cha mteja hadi VPS. Ninatumia Wireguard kama ya haraka na rahisi kusanidi. Pia nina vipanga njia vya mteja kulingana na Linux (APU2 au kitu katika OpenWRT). Kwa upande wa Mikrotik / Cisco, unaweza kutumia itifaki zinazopatikana kwao kama OpenVPN na GRE-over-IPSEC.

Utambulisho na uelekezaji upya wa trafiki ya maslahi

Unaweza, bila shaka, kuzima trafiki yote ya mtandao kupitia nchi za kigeni. Lakini, uwezekano mkubwa, kasi ya kufanya kazi na maudhui ya ndani itateseka sana kutokana na hili. Pamoja, mahitaji ya bandwidth kwenye VPS yatakuwa ya juu zaidi.

Kwa hivyo, tutahitaji kwa namna fulani kutenga trafiki kwa tovuti zilizozuiwa na kwa kuchagua kuielekeza kwenye handaki. Hata kama baadhi ya trafiki "ziada" inafika huko, bado ni bora zaidi kuliko kuendesha kila kitu kwenye handaki.

Ili kudhibiti trafiki, tutatumia itifaki ya BGP na kutangaza njia za mitandao muhimu kutoka VPS yetu hadi kwa wateja. Wacha tuchukue BIRD kama mojawapo ya damoni za BGP zinazofanya kazi zaidi na zinazofaa.

IP

Kwa kuzuia na IP, kila kitu ni wazi: tunatangaza tu IP zote zilizozuiwa na VPS. Shida ni kwamba kuna subnets elfu 600 kwenye orodha ambayo API inarudi, na idadi kubwa yao ni / 32 majeshi. Idadi hii ya njia inaweza kuchanganya vipanga njia dhaifu vya mteja.

Kwa hivyo, wakati wa kusindika orodha, iliamuliwa kufupisha hadi mtandao / 24 ikiwa ina majeshi 2 au zaidi. Kwa hivyo, idadi ya njia ilipunguzwa hadi ~ 100 elfu. Nakala ya hii itafuata.

Vikoa

Ni ngumu zaidi na kuna njia kadhaa. Kwa mfano, unaweza kusakinisha Squid inayoonekana kwenye kila kipanga njia cha mteja na utekeleze HTTP hapo na uchunguze kwa kupeana mkono kwa TLS ili kupata URL iliyoombwa katika hali ya kwanza na kikoa kutoka kwa SNI katika pili.

Lakini kutokana na aina zote za TLS1.3 + eSNI mpya, uchanganuzi wa HTTPS unazidi kuwa halisi kila siku. Ndio, na miundombinu kwa upande wa mteja inazidi kuwa ngumu - itabidi utumie angalau OpenWRT.

Kwa hivyo, niliamua kuchukua njia ya kukatiza majibu kwa maombi ya DNS. Hapa pia, DNS-over-TLS / HTTPS yoyote huanza kuelea juu ya kichwa chako, lakini tunaweza (kwa sasa) kudhibiti sehemu hii kwenye mteja - ama kuizima au kutumia seva yako mwenyewe kwa DoT / DoH.

Jinsi ya kuzuia DNS?

Hapa, pia, kunaweza kuwa na mbinu kadhaa.

  • Kuzuia trafiki ya DNS kupitia PCAP au NFLOG
    Njia hizi zote mbili za kukamata zinatekelezwa katika matumizi sidmat. Lakini haijaungwa mkono kwa muda mrefu na utendaji ni wa zamani sana, kwa hivyo bado unahitaji kuandika kuunganisha kwa hiyo.
  • Uchambuzi wa kumbukumbu za seva za DNS
    Kwa bahati mbaya, virudishi vinavyojulikana kwangu haviwezi kuweka majibu, lakini maombi tu. Kimsingi, hii ni ya kimantiki, kwani, tofauti na maombi, majibu yana muundo mgumu na ni ngumu kuyaandika kwa maandishi.
  • DNStap
    Kwa bahati nzuri, wengi wao tayari wanaunga mkono DNStap kwa kusudi hili.

DNSTap ni nini?

Bypass ILV kuzuia na DNStap na BGP

Ni itifaki ya seva-teja kulingana na Vibafa vya Itifaki na Mitiririko ya Fremu kwa ajili ya kuhamisha kutoka kwa seva ya DNS hadi kwa mkusanyaji wa maswali na majibu yaliyopangwa ya DNS. Kimsingi, seva ya DNS hutuma metadata ya hoja na majibu (aina ya ujumbe, IP ya mteja/seva, n.k.) pamoja na ujumbe kamili wa DNS katika umbo (jina la pili) ambamo hufanya kazi nao kwenye mtandao.

Ni muhimu kuelewa kwamba katika dhana ya DNStap, seva ya DNS hufanya kama mteja na mkusanyaji hufanya kama seva. Hiyo ni, seva ya DNS inaunganisha kwa mtoza, na sio kinyume chake.

Leo DNStap inatumika katika seva zote maarufu za DNS. Lakini, kwa mfano, BIND katika usambazaji wengi (kama Ubuntu LTS) mara nyingi hujengwa kwa sababu fulani bila msaada wake. Kwa hiyo hebu tusijisumbue na kuunganisha tena, lakini kuchukua recursor nyepesi na kasi - Unbound.

Jinsi ya kupata DNStap?

Kuna baadhi idadi Huduma za CLI za kufanya kazi na mtiririko wa matukio ya DNStap, lakini hazifai kusuluhisha tatizo letu. Kwa hivyo, niliamua kuunda baiskeli yangu mwenyewe ambayo itafanya kila kitu kinachohitajika: dnstap-bgp

Algorithm ya kazi:

  • Inapozinduliwa, hupakia orodha ya vikoa kutoka kwa faili ya maandishi, inageuza (habr.com -> com.habr), haijumuishi mistari iliyovunjika, nakala na vikoa vidogo (yaani ikiwa orodha ina habr.com na www.habr.com, itapakiwa tu ya kwanza) na huunda mti wa kiambishi awali kwa ajili ya kutafuta haraka kupitia orodha hii
  • Inafanya kazi kama seva ya DNSTap, inasubiri muunganisho kutoka kwa seva ya DNS. Kimsingi, inasaidia soketi zote mbili za UNIX na TCP, lakini seva za DNS ninazojua zinaweza kutumia soketi za UNIX pekee.
  • Pakiti zinazoingia za DNStap kwanza huondolewa kwenye muundo wa Protobuf, na kisha ujumbe wa DNS yenyewe, ulio katika mojawapo ya sehemu za Protobuf, huchanganuliwa hadi kiwango cha rekodi za DNS RR.
  • Inaangaliwa kama mwenyeji aliyeombwa (au kikoa kikuu) iko kwenye orodha iliyopakiwa, ikiwa sivyo, jibu limepuuzwa.
  • Ni A/AAAA/CNAME RR pekee ndizo zinazochaguliwa kutoka kwa jibu na anwani zinazolingana za IPv4/IPv6 hutolewa kutoka kwao.
  • Anwani za IP zimewekwa akiba na TTL inayoweza kusanidiwa na kutangazwa kwa programu zingine zote za BGP zilizosanidiwa
  • Wakati wa kupokea jibu linaloelekeza kwa IP iliyohifadhiwa tayari, TTL yake inasasishwa
  • Baada ya muda wa TTL kuisha, ingizo huondolewa kutoka kwa akiba na kutoka kwa matangazo ya BGP

Utendaji wa ziada:

  • Kusoma upya orodha ya vikoa kwa SIGHUP
  • Kuweka akiba katika ulandanishi na matukio mengine dnstap-bgp kupitia HTTP/JSON
  • Rudufu kashe kwenye diski (katika hifadhidata ya BoltDB) ili kurejesha yaliyomo baada ya kuwasha upya
  • Usaidizi wa kubadili kwa nafasi tofauti ya majina ya mtandao (kwa nini hii inahitajika itaelezwa hapa chini)
  • Msaada wa IPv6

Ukomo:

  • Vikoa vya IDN bado havitumiki
  • Mipangilio michache ya BGP

Nilikusanya RPM na DEB vifurushi kwa ajili ya ufungaji rahisi. Inapaswa kufanya kazi kwenye OS zote za hivi karibuni zilizo na systemd. hawana tegemeo lolote.

Mpango

Kwa hiyo, hebu tuanze kukusanya vipengele vyote pamoja. Kama matokeo, tunapaswa kupata kitu kama topolojia hii ya mtandao:
Bypass ILV kuzuia na DNStap na BGP

Mantiki ya kazi, nadhani, ni wazi kutoka kwa mchoro:

  • Mteja ameweka seva yetu kama DNS, na hoja za DNS lazima zipitie VPN. Hii ni muhimu ili mtoa huduma asiweze kutumia uingiliaji wa DNS kuzuia.
  • Wakati wa kufungua tovuti, mteja hutuma swali la DNS kama vile "IPs za xxx.org ni zipi"
  • unbound inasuluhisha xxx.org (au inaichukua kutoka kwa kache) na kutuma jibu kwa mteja "xxx.org ina IP kama vile", inakili kwa sambamba kupitia DNSTap
  • dnstap-bgp inatangaza anwani hizi Kuzaliwa kupitia BGP ikiwa kikoa kiko kwenye orodha iliyozuiwa
  • Kuzaliwa inatangaza njia ya kufikia IP hizi kwa next-hop self kipanga njia cha mteja
  • Pakiti zinazofuata kutoka kwa mteja hadi IPs hizi hupitia handaki

Kwenye seva, kwa njia za tovuti zilizozuiwa, mimi hutumia meza tofauti ndani ya BIRD na haiingiliani na OS kwa njia yoyote.

Mpango huu una shida: pakiti ya kwanza ya SYN kutoka kwa mteja, uwezekano mkubwa, itakuwa na muda wa kuondoka kupitia mtoa huduma wa ndani. njia haijatangazwa mara moja. Na hapa chaguzi zinawezekana kulingana na jinsi mtoa huduma anavyozuia. Ikiwa anaacha tu trafiki, basi hakuna shida. Na ikiwa ataielekeza kwa DPI fulani, basi (kinadharia) athari maalum zinawezekana.

Inawezekana pia kuwa wateja hawaheshimu miujiza ya DNS TTL, ambayo inaweza kusababisha mteja kutumia maingizo ya zamani kutoka kwa kashe yake iliyooza badala ya kuuliza Unbound.

Kwa mazoezi, sio ya kwanza wala ya pili iliyosababisha shida kwangu, lakini mileage yako inaweza kutofautiana.

Urekebishaji wa Seva

Kwa urahisi wa kusonga, niliandika jukumu kwa Ansible. Inaweza kusanidi seva na wateja kulingana na Linux (iliyoundwa kwa usambazaji wa msingi wa deb). Mipangilio yote ni dhahiri kabisa na imewekwa hesabu.yml. Jukumu hili limekatwa kutoka kwa kitabu changu kikubwa cha kucheza, kwa hivyo kinaweza kuwa na makosa - kuvuta maombi karibu πŸ™‚

Wacha tupitie sehemu kuu.

BGP

Kuendesha daemoni mbili za BGP kwenye seva pangishi kuna tatizo la kimsingi: BIRD hataki kusanidi kutazama BGP na mwenyeji wa ndani (au kiolesura chochote cha ndani). Kutoka kwa neno kabisa. Googling na kusoma orodha ya barua haikusaidia, wanadai kuwa hii ni kwa muundo. Labda kuna njia fulani, lakini sikuipata.

Unaweza kujaribu daemon nyingine ya BGP, lakini napenda BIRD na hutumiwa kila mahali na mimi, sitaki kutoa vyombo.

Kwa hivyo, nilificha dnstap-bgp ndani ya nafasi ya jina ya mtandao, ambayo imeunganishwa na mzizi kupitia kiolesura cha veth: ni kama bomba, miisho yake ambayo hutoka katika nafasi tofauti za majina. Katika kila ncha hizi, tunapachika anwani za IP za faragha za p2p ambazo haziendi zaidi ya seva pangishi, ili ziwe chochote. Huu ni utaratibu sawa unaotumiwa kupata michakato ndani kupendwa na wote Docker na vyombo vingine.

Kwa hili iliandikwa hati na utendaji ambao tayari umeelezewa hapo juu wa kujikokota kwa nywele hadi nafasi nyingine ya jina uliongezwa kwa dnstap-bgp. Kwa sababu hii, lazima iendeshwe kama mzizi au itolewe kwa CAP_SYS_ADMIN binary kupitia setcap amri.

Mfano wa hati ya kuunda nafasi ya majina

#!/bin/bash

NS="dtap"

IP="/sbin/ip"
IPNS="$IP netns exec $NS $IP"

IF_R="veth-$NS-r"
IF_NS="veth-$NS-ns"

IP_R="192.168.149.1"
IP_NS="192.168.149.2"

/bin/systemctl stop dnstap-bgp || true

$IP netns del $NS > /dev/null 2>&1
$IP netns add $NS

$IP link add $IF_R type veth peer name $IF_NS
$IP link set $IF_NS netns $NS

$IP addr add $IP_R remote $IP_NS dev $IF_R
$IP link set $IF_R up

$IPNS addr add $IP_NS remote $IP_R dev $IF_NS
$IPNS link set $IF_NS up

/bin/systemctl start dnstap-bgp

dnstap-bgp.conf

namespace = "dtap"
domains = "/var/cache/rkn_domains.txt"
ttl = "168h"

[dnstap]
listen = "/tmp/dnstap.sock"
perm = "0666"

[bgp]
as = 65000
routerid = "192.168.149.2"

peers = [
    "192.168.149.1",
]

ndege.conf

router id 192.168.1.1;

table rkn;

# Clients
protocol bgp bgp_client1 {
    table rkn;
    local as 65000;
    neighbor 192.168.1.2 as 65000;
    direct;
    bfd on;
    next hop self;
    graceful restart;
    graceful restart time 60;
    export all;
    import none;
}

# DNSTap-BGP
protocol bgp bgp_dnstap {
    table rkn;
    local as 65000;
    neighbor 192.168.149.2 as 65000;
    direct;
    passive on;
    rr client;
    import all;
    export none;
}

# Static routes list
protocol static static_rkn {
    table rkn;
    include "rkn_routes.list";
    import all;
    export none;
}

rkn_routes.list

route 3.226.79.85/32 via "ens3";
route 18.236.189.0/24 via "ens3";
route 3.224.21.0/24 via "ens3";
...

DNS

Kwa chaguo-msingi, katika Ubuntu, binary Unbound imefungwa na wasifu wa AppArmor, ambayo inakataza kuunganisha kwa kila aina ya soketi za DNStap. Unaweza kufuta wasifu huu, au kuuzima:

# cd /etc/apparmor.d/disable && ln -s ../usr.sbin.unbound .
# apparmor_parser -R /etc/apparmor.d/usr.sbin.unbound

Labda hii inapaswa kuongezwa kwenye kitabu cha kucheza. Ni bora, bila shaka, kurekebisha wasifu na kutoa haki muhimu, lakini nilikuwa mvivu sana.

unbound.conf

server:
    chroot: ""
    port: 53
    interface: 0.0.0.0
    root-hints: "/var/lib/unbound/named.root"
    auto-trust-anchor-file: "/var/lib/unbound/root.key"
    access-control: 192.168.0.0/16 allow

remote-control:
    control-enable: yes
    control-use-cert: no

dnstap:
    dnstap-enable: yes
    dnstap-socket-path: "/tmp/dnstap.sock"
    dnstap-send-identity: no
    dnstap-send-version: no

    dnstap-log-client-response-messages: yes

Inapakua na kuchakata orodha

Hati ya kupakua na kuchakata orodha ya anwani za IP
Inapakua orodha, muhtasari wa kiambishi awali pfx. Katika usi_ongeza ΠΈ usifanye_muhtasari unaweza kuwaambia IP na mitandao kuruka au kutofanya muhtasari. Nilihitaji. subnet ya VPS yangu ilikuwa kwenye orodha ya kuzuia πŸ™‚

Jambo la kuchekesha ni kwamba API ya RosKomSvoboda inazuia maombi na wakala chaguo-msingi wa Python. Inaonekana mtoto wa hati ameipata. Kwa hivyo, tunaibadilisha kuwa Ognelis.

Kufikia sasa, inafanya kazi tu na IPv4. sehemu ya IPv6 ni ndogo, lakini itakuwa rahisi kurekebisha. Isipokuwa lazima utumie ndege6 pia.

rkn.py

#!/usr/bin/python3

import json, urllib.request, ipaddress as ipa

url = 'https://api.reserve-rbl.ru/api/v2/ips/json'
pfx = '24'

dont_summarize = {
    # ipa.IPv4Network('1.1.1.0/24'),
}

dont_add = {
    # ipa.IPv4Address('1.1.1.1'),
}

req = urllib.request.Request(
    url,
    data=None, 
    headers={
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'
    }
)

f = urllib.request.urlopen(req)
ips = json.loads(f.read().decode('utf-8'))

prefix32 = ipa.IPv4Address('255.255.255.255')

r = {}
for i in ips:
    ip = ipa.ip_network(i)
    if not isinstance(ip, ipa.IPv4Network):
        continue

    addr = ip.network_address

    if addr in dont_add:
        continue

    m = ip.netmask
    if m != prefix32:
        r[m] = [addr, 1]
        continue

    sn = ipa.IPv4Network(str(addr) + '/' + pfx, strict=False)

    if sn in dont_summarize:
        tgt = addr
    else:
        tgt = sn

    if not sn in r:
        r[tgt] = [addr, 1]
    else:
        r[tgt][1] += 1

o = []
for n, v in r.items():
    if v[1] == 1:
        o.append(str(v[0]) + '/32')
    else:
        o.append(n)

for k in o:
    print(k)

Hati ya kusasisha
Ninaendesha kwenye taji mara moja kwa siku, labda ni thamani ya kuivuta kila masaa 4. hiki, kwa maoni yangu, ni kipindi cha usasishaji ambacho RKN inahitaji kutoka kwa watoa huduma. Zaidi, wana vizuizi vingine vya haraka sana, ambavyo vinaweza kufika haraka.

Je, yafuatayo:

  • Huendesha hati ya kwanza na kusasisha orodha ya njia (rkn_routes.list) kwa NDEGE
  • Pakia upya NDEGE
  • Inasasisha na kusafisha orodha ya vikoa vya dnstap-bgp
  • Pakia upya dnstap-bgp

rkn_update.sh

#!/bin/bash

ROUTES="/etc/bird/rkn_routes.list"
DOMAINS="/var/cache/rkn_domains.txt"

# Get & summarize routes
/opt/rkn.py | sed 's/(.*)/route 1 via "ens3";/' > $ROUTES.new

if [ $? -ne 0 ]; then
    rm -f $ROUTES.new
    echo "Unable to download RKN routes"
    exit 1
fi

if [ -e $ROUTES ]; then
    mv $ROUTES $ROUTES.old
fi

mv $ROUTES.new $ROUTES

/bin/systemctl try-reload-or-restart bird

# Get domains
curl -s https://api.reserve-rbl.ru/api/v2/domains/json -o - | jq -r '.[]' | sed 's/^*.//' | sort | uniq > $DOMAINS.new

if [ $? -ne 0 ]; then
    rm -f $DOMAINS.new
    echo "Unable to download RKN domains"
    exit 1
fi

if [ -e $DOMAINS ]; then
    mv $DOMAINS $DOMAINS.old
fi

mv $DOMAINS.new $DOMAINS

/bin/systemctl try-reload-or-restart dnstap-bgp

Ziliandikwa bila kufikiria sana, kwa hivyo ikiwa unaona kitu ambacho kinaweza kuboreshwa - nenda kwa hiyo.

Mpangilio wa mteja

Hapa nitatoa mifano kwa ruta za Linux, lakini katika kesi ya Mikrotik / Cisco inapaswa kuwa rahisi zaidi.

Kwanza, tunaanzisha BIRD:

ndege.conf

router id 192.168.1.2;
table rkn;

protocol device {
    scan time 10;
};

# Servers
protocol bgp bgp_server1 {
    table rkn;
    local as 65000;
    neighbor 192.168.1.1 as 65000;
    direct;
    bfd on;
    next hop self;
    graceful restart;
    graceful restart time 60;
    rr client;
    export none;
    import all;
}

protocol kernel {
    table rkn;
    kernel table 222;
    scan time 10;
    export all;
    import none;
}

Kwa hivyo, tutasawazisha njia zilizopokelewa kutoka kwa BGP na jedwali la kuelekeza kernel nambari 222.

Baada ya hayo, inatosha kuuliza kernel kutazama sahani hii kabla ya kuangalia ile chaguo-msingi:

# ip rule add from all pref 256 lookup 222
# ip rule
0:  from all lookup local
256:    from all lookup 222
32766:  from all lookup main
32767:  from all lookup default

Kila kitu, inabakia kusanidi DHCP kwenye kipanga njia ili kusambaza anwani ya IP ya handaki ya seva kama DNS, na mpango uko tayari.

Mapungufu

Na algorithm ya sasa ya kutengeneza na kuchakata orodha ya vikoa, inajumuisha, kati ya mambo mengine, youtube.com na CDN zake.

Na hii inaongoza kwa ukweli kwamba video zote zitapitia VPN, ambayo inaweza kuziba chaneli nzima. Labda inafaa kuandaa orodha ya vikoa-vilivyotengwa ambavyo vinazuia RKN kwa wakati huu, matumbo ni nyembamba. Na uwaruke wakati wa kuchanganua.

Hitimisho

Njia iliyoelezewa hukuruhusu kupita karibu kizuizi chochote ambacho watoa huduma wanatekeleza kwa sasa.

Katika kanuni, dnstap-bgp inaweza kutumika kwa madhumuni mengine yoyote ambapo kiwango fulani cha udhibiti wa trafiki kinahitajika kulingana na jina la kikoa. Kumbuka tu kwamba katika wakati wetu, tovuti elfu zinaweza kunyongwa kwenye anwani sawa ya IP (nyuma ya Cloudflare, kwa mfano), kwa hivyo njia hii ina usahihi wa chini.

Lakini kwa mahitaji ya kufuli kwa kupita, hii inatosha.

Nyongeza, uhariri, maombi ya kuvuta - karibu!

Chanzo: mapenzi.com

Kuongeza maoni