24 Jun 2020
|
IDE
sublime
SSH 터널링
SSH 터널링에는 크게 로컬 터널링(Local Tunneling), 리모트 터널링(Remote Tunneling), 다이나믹 터널링(Dynamic Tunneling)이 있습니다.
암호화를 이용한 데이터 패킷 전송 등에 사용되는데, 여기서는 로컬 터널링과 리모트 터널링에 대해 설명해봅니다.
경유 서버 설정
터널링을 위해서는 경유 서버가 필요합니다. 경유 서버에서 다음 설정을 해줍니다.
/etc/ssh/sshd_config
파일에 다음 내용을 추가해줍니다.
GatewayPorts yes
AllowTcpForwarding yes
그 이후
sudo service ssh restart
명령어로 ssh 데몬 서비스를 다시 실행합니다.
Local Tunneling
로컬에 있는 특정 포트를 다른 서버 주소로 연결하는 방식입니다.
다음과 같은 커맨드로 사용할 수 있습니다.
ssh -L sourcePort:forwardToHost:destPort connectToHost
ssh -L [로컬 PC 포트]:[타켓 서버 주소]:[타켓 서버 포트] [경유 서버 주소]
ex)
ssh -L 80:intra.example.com:80 gw.example.com
위 명령어는 ‘gw.example.com’ 서버를 경유 서버로 설정하고, 로컬 PC의 80 포트를 ‘ntra.example.com’ 서버의 80 포트로 연결하는
예제입니다.
조금 응용하면 다음과 같은 예제가 가능합니다.
아마존 서버(AWS)의 ssh 서버 포트가 기본적으로 22로 되어 있는데, 이를 8080 포트로 바꾸는 명령어는 다음과 같습니다.
이 경우는 AWS 서버가 타켓 서버가 됨과 동시에 로컬 PC 역할도 담당합니다.
먼저 아마존 서버에 접속한 다음
ssh -i snowdeer-key.pem -L 8080:localhost:22 localhost
명령어를 수행하면 됩니다.
이제 다른 PC에서 AWS 서버에 SSH 접속을 할 때 기존 22번 포트가 아닌 8080 포트를 사용해서 접속할 수 있습니다.
ssh -i snowdeer-key.pem -p 8080 ubuntu@xxx.xxx.xxx.xxx
Remote Tunneling
ssh -R sourcePort:forwardToHost:destPort connectToHost
ssh -R [오픈할 PC 포트]:[타켓 서버 주소]:[타켓 서버 포트] [경유 서버 주소]
ex)
ssh -R 9000:localhost:3000 user@example.com
위 예제는 로컬 PC의 3000 포트를 경유 서버의 9000 번 포트에 바인딩하는 예제입니다.
이 명령어 실행한 다음 example.com:9000
주소로 패킷을 주고 받을 수 있습니다.
17 Jun 2020
|
Flutter
Flutter Network Image
네트워크로 이미지 받으려면 먼저 Permission을 부여해줘야 합니다.
MacOS 기준으로 macos/Runner/DebugProfile.entitlements
파일에 권한을 줄 수 있습니다.
<key>com.apple.security.network.client</key>
<true/>
안드로이드 같은 경우는 AndroidManifest.xml
파일에 인터넷 권한을 부여하면 됩니다.
예제 코드
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Network Image Example',
home: Scaffold(
appBar: AppBar(
title: Text('Network Image Example'),
),
body: NetworkImageWidget(),
),
);
}
}
class NetworkImageWidget extends StatelessWidget {
final url = 'https://snowdeer.github.io/public/img/hello_page.jpg';
@override
Widget build(BuildContext context) {
return Center(
child: Image.network(url),
);
}
}
16 Jun 2020
|
Flutter
Flutter SnackBar
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SnackBar Example',
home: Scaffold(
appBar: AppBar(
title: Text('SnackBar Example'),
),
body: SnackBarPage(),
),
);
}
}
class SnackBarPage extends StatelessWidget {
final sb = SnackBar(
content: Text('Hello, SnowDeer ~!!'),
action: SnackBarAction(
label: 'ok',
onPressed: () {},
),
);
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text('SnackBar'),
onPressed: () {
Scaffold.of(context).showSnackBar(sb);
},
),
);
}
}
15 Jun 2020
|
Flutter
Flutter Gallery
Flutter Gallery에 가면 많은 Flutter Widget들의 모습과 예제들,
코드 등을 얻을 수 있습니다.
- GitHub: https://github.com/flutter/flutter/tree/master/dev/integration_tests/flutter_gallery
- 샘플 예제: https://flutter.github.io/samples/#
- 공식 레퍼런스: https://flutter.dev/docs
15 Jun 2020
|
Flutter
Flutter Drawer
Flutter에서 Drawer 사용은 아주 간단합니다. 거의 기본적으로 쓰는 위젯은 Scaffold
위젯에 drawer
속성을 갖고 있습니다.
따라서 다음 코드처럼만 작성해도 Drawer를 사용할 수 있습니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Drawer Example',
home: Scaffold(
appBar: AppBar(
title: Text('Drawer Widget'),
),
drawer: Drawer(),
),
);
}
}
하지만, 일반적인 Drawer라고 하면 Header 부분도 있어야 하고, 리스트도 있어야 하니깐 다음과 같이 꾸며줄 수 있습니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final appTitle = 'Drawer Example';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Center(child: Text('Drawer Example')),
drawer: Drawer(
// Add a ListView to the drawer. This ensures the user can scroll
// through the options in the drawer if there isn't enough vertical
// space to fit everything.
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: [
DrawerHeader(
child: Text('Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
],
),
),
);
}
}
보다 자세한 내용은 여기를 참고하세요.