—
Sürekli aynı soruna takılıyordum: SSH ile bağlandığım uzak bir sunucudan
küçük bir metin parçasını — bir log satırını, bir parolayı, bir container'ın
çıktısını — başka bir makineye taşımam gerekiyor, ama pano (clipboard) diye
bir şey yok ortada. Kurumsal politikayla pano erişimi kilitlenmiş bir
dizüstü. Ortak panosu olmayan bir container. Slack elimin altında ama bir
veritabanı parolasını sonsuza kadar arşivde kalacak bir kanala yapıştırmak
hiç de iyi bir fikir değil.
Bu yüzden **CPYNET**'i yaptım — arayüzü tek bir şey olan bir paylaşım aracı:
`curl`.
```bash
echo "merhaba dünya" | curl --data-binary @- https://cpynet.com/
# https://cpynet.com/482913
curl https://cpynet.com/482913
# merhaba dünya
```
Hepsi bu kadar. Hesap yok, API anahtarı yok, tıklanacak bir arayüz yok. İki
`curl` çağrısı, ve aralarında hiçbir ortak noktası olmayan iki makine
arasında metin taşınmış oluyor.
## Gerçekten "okunduğu an silinir"
Yukarıdaki paste, ikinci `curl` komutu çalıştığı **an** yok oluyor. "24 saat
sonra" değil, "sen silene kadar" hiç değil — tam olarak okunduğu anda. Aynı
kodu (aynı makineden bile olsa) ikinci kez okumaya çalışırsan düz bir `404`
alırsın. Ayrıca bir sayaç da var (varsayılan 2 dakika, ayarlanabilir): hiç
kimse okumasa bile süre dolunca otomatik siliniyor.
Bunların hiçbiri diske yazılmıyor. Sunucu tarafında bir mutex'in arkasında
duran sade bir Go `map`'i — process ayakta olduğu sürece bellekte, restart
olduğu an henüz okunmamış her şey birlikte yok oluyor. Bu bir sınırlama
değil, tam olarak amaç: diskte bir yerlere yazan bir "okununca silinir"
aracı, aslında hiçbir şeyi gerçekten silmiyor demektir.
## curl komutlarını ezberlemek istemiyorsan: `cpy` / `pst`
```bash
curl -s https://cpynet.com/install.sh -o install.sh && bash -n install.sh && . install.sh
```
Bu tek satır, iki shell fonksiyonu kuruyor:
```bash
$ journalctl -u myservice -n 200 | cpy
482913
curl https://cpynet.com/482913
# başka bir makinede
$ pst 482913
Aug 08 14:02:11 myservice[1823]: connection refused: db.internal:5432
...
```
`pst`, bulabilirse metni otomatik olarak panoya da kopyalıyor
(pbcopy/wl-copy/xclip/xsel/clip.exe) — ama bu sadece bir kolaylık, hiçbir
zaman zorunlu değil. Her iki fonksiyon da web arayüzünün kullandığı aynı
HTTP endpoint'leriyle konuşuyor; "gerçek ürün" web arayüzü, curl pipe'ı ise
onun basitleştirilmiş bir versiyonu değil — ikisi de aynı şey.
## İki farklı şifreleme katmanı, iki farklı tehdit modeli için
**Parola koruması** (`?p=` ya da `cpy -password=xxx`): AES-256-GCM, anahtar
PBKDF2 ile türetiliyor (210.000 iterasyon — OWASP'ın güncel minimum önerisi).
Sunucu, parolayı doğrulamak için metni anlık olarak çözüyor, sonra tekrar
şifreleyerek saklıyor. Bu "sunucuya güveniyorum, sadece diskte düz metin
durmasın" modeli — bir disk sızıntısına ya da yedek dosyasına karşı korur,
sunucunun kendisine karşı değil.
**Gerçek uçtan uca şifreleme** (yaz sekmesindeki kalkan ikonu, ya da
terminalde `cpy -e`) tamamen farklı bir şey: anahtar client tarafında
üretiliyor ve sunucuya hiç gönderilmiyor. Web tarafında WebCrypto
AES-256-GCM kullanılıyor, anahtar linkin `#key=` kısmında taşınıyor —
tarayıcılar fragment'ı sunucuya hiçbir zaman göndermez, yani bu fiziksel
olarak sızamaz. CLI tarafında ise `openssl enc -aes-256-cbc -pbkdf2` ile
rastgele bir passphrase üretiliyor, bilinçli olarak linke değil ayrı bir
satıra basılıyor. İki bağımsız implementasyon, birbiriyle uyumlu olmak
zorunda bile değiller — ikisi de aynı garantiye varıyor: sunucu yalnızca
şifreli metni görüyor.
## Diğer özellikler, kısaca
- **QR kod** — linki telefonla taratınca doğrudan tarayıcıda açılıp
çözülüyor. Tamamen client-side, bağımlılıksız bir QR encoder ile
üretiliyor; hiçbir şey üçüncü bir servise gitmiyor.
- **Canlı bildirim** — paste okunduğu an, onu gönderen sekme SSE ile anında
haberdar oluyor, polling yok.
- **Küçük dosya desteği** — sadece izin verilen (ve gerçek içeriği de
kontrol edilen — bir `.exe`'yi `.txt` diye yeniden adlandırıp yükleyemezsin)
uzantılar, indirirken orijinal dosya adı ve içerik tipiyle geri geliyor.
- **Netcat fallback** — curl'ün bile olmadığı minimal ortamlar için:
`nc host port < file` aynı şekilde çalışıyor.
- **IP başına hız sınırlama** — 6 haneli kod alanını brute-force'a karşı
gerçekten güvenli kılan da bu.
- Web arayüzü opsiyonel. Orada olması "bazen terminale hiç girmek
istemezsin" içindir — terminal yolu hiçbir zaman "yedek plan" olmadı,
asıl yol oydu.
## Denemek istersen
```bash
curl -s https://cpynet.com/install.sh -o install.sh && bash -n install.sh && . install.sh
echo "çalışıyor" | cpy
```